PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.6.9.4
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.6.9.4
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 / databases / class-lp-user-items-db.php

class-lp-user-items-db.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.6.9.4, at inc/databases/class-lp-user-items-db.php

881 lines 23.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 /**
8 * Class LP_User_Items_DB
9 *
10 * @since 3.2.8.6
11 * @version 1.0.3
12 * @author tungnx
13 */
14 class LP_User_Items_DB extends LP_Database {
15 private static $_instance;
16 public static $user_item_id_col = 'learnpress_user_item_id';
17 public static $extra_value_col = 'extra_value';
18
19 protected function __construct() {
20 parent::__construct();
21 }
22
23 public static function getInstance() {
24 if ( is_null( self::$_instance ) ) {
25 self::$_instance = new self();
26 }
27
28 return self::$_instance;
29 }
30
31 /**
32 * Get users items
33 *
34 * @return array|null|int|string
35 * @throws Exception
36 * @since 4.1.6.9
37 * @version 1.0.0
38 */
39 public function get_user_items( LP_User_Items_Filter $filter, int &$total_rows = 0 ) {
40 $default_fields = $this->get_cols_of_table( $this->tb_lp_user_items );
41 $filter->fields = array_merge( $default_fields, $filter->fields );
42
43 if ( empty( $filter->collection ) ) {
44 $filter->collection = $this->tb_lp_user_items;
45 }
46
47 if ( empty( $filter->collection_alias ) ) {
48 $filter->collection_alias = 'ui';
49 }
50
51 if ( $filter->ref_id ) {
52 $filter->where[] = $this->wpdb->prepare( 'AND ui.ref_id = %d', $filter->ref_id );
53 }
54
55 $filter = apply_filters( 'lp/user_items/query/filter', $filter );
56
57 return $this->execute( $filter, $total_rows );
58 }
59
60 /**
61 * Get items by user_item_id | this is id where item_id = course_id
62 *
63 * @param LP_User_Items_Filter $filter
64 * @param bool $force_cache
65 *
66 * @return object
67 * @throws Exception
68 * Todo: tungnx need set paginate - apply when do load API
69 */
70 public function get_user_course_items( LP_User_Items_Filter $filter, bool $force_cache = false ) {
71 $key_first_cache = 'course_items/' . $filter->user_id . '/' . $filter->parent_id;
72 $course_items_cache = LP_Cache::cache_load_first( 'get', $key_first_cache );
73 if ( false !== $course_items_cache && ! $force_cache ) {
74 return $course_items_cache;
75 }
76
77 $query = $this->wpdb->prepare(
78 "SELECT * FROM $this->tb_lp_user_items
79 WHERE parent_id = %d
80 AND ref_type = %s
81 AND user_id = %d
82 ",
83 $filter->parent_id,
84 LP_COURSE_CPT,
85 $filter->user_id
86 );
87
88 $course_items = $this->wpdb->get_results( $query );
89
90 $this->check_execute_has_error();
91
92 LP_Cache::cache_load_first( 'set', $key_first_cache, $course_items );
93
94 return $course_items;
95 }
96
97 /**
98 * Remove items' of course and user learned
99 *
100 * @param LP_User_Items_Filter $filter .
101 *
102 * @return bool|int
103 * @throws Exception .
104 * @TODO tungnx - recheck this function
105 */
106 public function remove_items_of_user_course( LP_User_Items_Filter $filter ) {
107 $query_extra = '';
108
109 // Check valid user.
110 if ( ! is_user_logged_in() || ( ! current_user_can( ADMIN_ROLE ) && get_current_user_id() != $filter->user_id ) ) {
111 throw new Exception( __( 'User invalid!', 'learnpress' ) . ' | ' . __FUNCTION__ );
112 }
113
114 if ( - 1 < $filter->limit ) {
115 $query_extra .= " LIMIT $filter->limit";
116 }
117
118 $query = $this->wpdb->prepare(
119 "DELETE FROM {$this->tb_lp_user_items}
120 WHERE parent_id = %d
121 $query_extra;
122 ",
123 $filter->parent_id
124 );
125
126 return $this->wpdb->query( $query );
127 }
128
129 /*public function get_item_status( $item_id, $course_id ) {
130 $query = $this->wpdb->prepare(
131 "
132 SELECT status FROM {$this->tb_lp_user_items}
133 WHERE ref_id = %d
134 AND ref_type = %s
135 AND item_id = %d
136 ",
137 $course_id,
138 'lp_course',
139 $item_id
140 );
141
142 return $this->wpdb->get_var( $query );
143 }*/
144
145 /**
146 * Insert/Update extra value
147 *
148 * @param int $user_item_id
149 * @param string $meta_key
150 * @param string $value
151 * @since 4.0.0
152 * @version 1.0.0
153 * @author tungnx
154 */
155 public function update_extra_value( $user_item_id = 0, $meta_key = '', $value = '' ) {
156 $data = array(
157 'learnpress_user_item_id' => $user_item_id,
158 'meta_key' => $meta_key,
159 'extra_value' => $value,
160 );
161 $format = array( '%s', '%s' );
162
163 $check_exist_data = $this->wpdb->get_var(
164 $this->wpdb->prepare(
165 "
166 SELECT meta_id FROM $this->tb_lp_user_itemmeta
167 WHERE " . self::$user_item_id_col . ' = %d
168 AND meta_key = %s
169 ',
170 $user_item_id,
171 $meta_key
172 )
173 );
174
175 if ( $check_exist_data ) {
176 $this->wpdb->update(
177 $this->tb_lp_user_itemmeta,
178 $data,
179 array(
180 self::$user_item_id_col => $user_item_id,
181 'meta_key' => $meta_key,
182 ),
183 $format
184 );
185 } else {
186 $this->wpdb->insert( $this->tb_lp_user_itemmeta, $data, $format );
187 }
188 }
189
190 /**
191 * Get extra value
192 *
193 * @param int $user_item_id
194 * @param string $meta_key
195 */
196 public function get_extra_value( $user_item_id = 0, $meta_key = '' ) {
197 return $this->wpdb->get_var(
198 $this->wpdb->prepare(
199 '
200 SELECT ' . self::$extra_value_col . " FROM $this->tb_lp_user_itemmeta
201 WHERE " . self::$user_item_id_col . ' = %d
202 AND meta_key = %s
203 ',
204 $user_item_id,
205 $meta_key
206 )
207 );
208 }
209
210 /**
211 * Re-set current item
212 * @param $course_id
213 * @param $item_id
214 * @editor hungkv
215 */
216 public function reset_course_current_item( $course_id, $item_id ) {
217 // Select all course enrolled
218 $query = $this->wpdb->prepare(
219 "
220 SELECT user_item_id
221 FROM {$this->wpdb->prefix}learnpress_user_items
222 WHERE status = %s AND item_id = %d AND graduation = %s
223 ",
224 'enrolled',
225 $course_id,
226 'in-progress'
227 );
228 $user_item_ids = $this->wpdb->get_col( $query );
229 if ( ! empty( $user_item_ids ) ) {
230 foreach ( $user_item_ids as $user_item_id ) {
231 // Check item is current item of all course
232 $query = $this->wpdb->prepare(
233 "
234 SELECT meta_value
235 FROM {$this->wpdb->prefix}learnpress_user_itemmeta
236 WHERE learnpress_user_item_id = %d
237 ",
238 $user_item_id
239 );
240 $meta_value_id = $this->wpdb->get_var( $query );
241 // Check if the deleted item is current item or not
242 if ( $meta_value_id == $item_id ) {
243 $course = learn_press_get_course( $course_id );
244 // update _curent_item to database
245 learn_press_update_user_item_meta( $user_item_id, '_current_item', $course->get_first_item_id() );
246 }
247 }
248 }
249 }
250
251 /**
252 * Get total courses is has graduation is 'in_progress'
253 *
254 * @param int $user_id
255 * @param string $status
256 * @return int
257 * @throws Exception
258 */
259 public function get_total_courses_has_status( int $user_id, string $status ): int {
260 $query = $this->wpdb->prepare(
261 "
262 SELECT COUNT(DISTINCT(ui.item_id)) total
263 FROM $this->tb_lp_user_items AS ui
264 WHERE ui.item_type = %s
265 AND ui.user_id = %d
266 AND ui.graduation = %s
267 ",
268 LP_COURSE_CPT,
269 $user_id,
270 $status
271 );
272
273 $this->check_execute_has_error();
274
275 return (int) $this->wpdb->get_var( $query );
276 }
277
278 /**
279 * Get number status by status, graduation...
280 *
281 * @param LP_User_Items_Filter $filter {user_id, item_type}
282 *
283 * @author tungnx
284 * @since 4.1.5
285 * @version 1.0.1
286 * @return object|null
287 * @throws Exception
288 */
289 public function count_status_by_items( LP_User_Items_Filter $filter ) {
290 $filter->only_fields[] = $this->wpdb->prepare( 'SUM(ui.graduation = %s) AS %s', LP_COURSE_GRADUATION_IN_PROGRESS, LP_COURSE_GRADUATION_IN_PROGRESS );
291 $filter->only_fields[] = $this->wpdb->prepare( 'SUM(ui.graduation = %s) AS %s', LP_COURSE_GRADUATION_FAILED, LP_COURSE_GRADUATION_FAILED );
292 $filter->only_fields[] = $this->wpdb->prepare( 'SUM(ui.graduation = %s) AS %s', LP_COURSE_GRADUATION_PASSED, LP_COURSE_GRADUATION_PASSED );
293 $filter->only_fields[] = $this->wpdb->prepare( 'SUM(ui.status = %s) AS %s', LP_COURSE_ENROLLED, LP_COURSE_ENROLLED );
294 $filter->only_fields[] = $this->wpdb->prepare( 'SUM(ui.status = %s) AS %s', LP_COURSE_PURCHASED, LP_COURSE_PURCHASED );
295 $filter->only_fields[] = $this->wpdb->prepare( 'SUM(ui.status = %s) AS %s', LP_COURSE_FINISHED, LP_COURSE_FINISHED );
296
297 $filter_user_attend_courses = new LP_User_Items_Filter();
298 $filter_user_attend_courses->only_fields = array( 'MAX(ui.user_item_id) AS user_item_id' );
299 $filter_user_attend_courses->where[] = $this->wpdb->prepare( 'AND ui.user_id = %s', $filter->user_id );
300 $filter_user_attend_courses->group_by = 'ui.item_id';
301 $filter_user_attend_courses->return_string_query = true;
302 $query_get_course_attend = $this->get_user_courses( $filter_user_attend_courses );
303
304 $filter->where[] = 'AND ui.user_item_id IN (' . $query_get_course_attend . ')';
305 $filter->return_string_query = true;
306
307 $filter = apply_filters( 'lp/user/course/query/count-status', $filter );
308
309 $query = $this->get_user_courses( $filter );
310
311 $this->check_execute_has_error();
312
313 return $this->wpdb->get_row( $query );
314 }
315
316 /**
317 * Get the newest item is course of user
318 *
319 * @param LP_User_Items_Filter $filter {course_id, user_id}
320 * @param bool $force_cache Reset first cache
321 *
322 * @return null|object
323 * @throws Exception
324 */
325 public function get_last_user_course( LP_User_Items_Filter $filter, bool $force_cache = false ) {
326 $key_load_first = 'user_course/' . $filter->user_id . '/' . $filter->item_id;
327 $user_course = LP_Cache::cache_load_first( 'get', $key_load_first );
328 if ( false !== $user_course && ! $force_cache ) {
329 return $user_course;
330 }
331
332 $query = $this->wpdb->prepare(
333 "SELECT user_item_id, user_id, item_id, item_type, status, graduation, ref_id, ref_type, start_time, end_time
334 FROM $this->tb_lp_user_items
335 WHERE item_type = %s
336 AND item_id = %d
337 AND user_id = %d
338 ORDER BY user_item_id DESC
339 LIMIT 1
340 ",
341 LP_COURSE_CPT,
342 $filter->item_id,
343 $filter->user_id
344 );
345
346 $result = $this->wpdb->get_row( $query );
347
348 $this->check_execute_has_error();
349
350 LP_Cache::cache_load_first( 'set', $key_load_first, $result );
351
352 return $result;
353 }
354
355 /**
356 * Get item of user and course
357 *
358 * @param LP_User_Items_Filter $filter {parent_id, item_id, user_id}
359 * @param bool $force_cache Reset first cache
360 *
361 * @return null|object
362 * @throws Exception
363 */
364 public function get_user_course_item( LP_User_Items_Filter $filter, bool $force_cache = false ) {
365 $key_load_first = 'user_course_item/' . $filter->user_id . '/' . $filter->item_id;
366 $user_course = LP_Cache::cache_load_first( 'get', $key_load_first );
367
368 if ( false !== $user_course && ! $force_cache ) {
369 return $user_course;
370 }
371
372 $WHERE = 'WHERE 1=1 ';
373
374 if ( $filter->parent_id ) {
375 $WHERE .= $this->wpdb->prepare( 'AND parent_id = %d ', $filter->parent_id );
376 }
377
378 if ( $filter->ref_id ) {
379 $WHERE .= $this->wpdb->prepare( 'AND ref_id = %d ', $filter->ref_id );
380 }
381
382 if ( $filter->ref_type ) {
383 $WHERE .= $this->wpdb->prepare( 'AND ref_type = %s ', $filter->ref_type );
384 }
385
386 if ( $filter->item_type ) {
387 $WHERE .= $this->wpdb->prepare( 'AND item_type = %s ', $filter->item_type );
388 }
389
390 $query = $this->wpdb->prepare(
391 "SELECT user_item_id, user_id, item_id, item_type, status, graduation, ref_id, ref_type, start_time, end_time, parent_id
392 FROM $this->tb_lp_user_items
393 $WHERE
394 AND item_id = %d
395 AND user_id = %d
396 ORDER BY user_item_id DESC
397 LIMIT 1
398 ",
399 $filter->item_id,
400 $filter->user_id
401 );
402
403 $result = $this->wpdb->get_row( $query );
404
405 $this->check_execute_has_error();
406
407 LP_Cache::cache_load_first( 'set', $key_load_first, $result );
408
409 return $result;
410 }
411
412 /**
413 * Get items of course by item type
414 *
415 * @param LP_User_Items_Filter $filter {$filter->parent_id, $filter->item_type, [$filter->item_id]}
416 * @throws Exception
417 */
418 public function get_user_course_items_by_item_type( LP_User_Items_Filter $filter ) {
419
420 $AND = '';
421
422 if ( $filter->item_type ) {
423 $AND .= $this->wpdb->prepare( ' AND item_type = %s', $filter->item_type );
424 }
425
426 if ( $filter->item_id ) {
427 $AND .= $this->wpdb->prepare( ' AND item_id = %d', $filter->item_id );
428 }
429
430 $query = $this->wpdb->prepare(
431 "SELECT user_item_id, user_id, item_id, item_type, status, graduation, ref_id, ref_type, start_time, end_time, parent_id
432 FROM $this->tb_lp_user_items
433 WHERE parent_id = %d
434 $AND
435 ",
436 $filter->parent_id
437 );
438
439 $result = $this->wpdb->{$filter->query_type}( $query );
440
441 $this->check_execute_has_error();
442
443 return $result;
444 }
445
446 /**
447 * Get user_item_id by course_id
448 *
449 * @param LP_User_Items_Filter $filter $filter->item_id
450 *
451 * @return array
452 */
453 public function get_user_items_by_course( LP_User_Items_Filter $filter ): array {
454 try {
455 // Check valid user.
456 if ( ! is_user_logged_in() ) {
457 throw new Exception( __( 'User invalid!', 'learnpress' ) . ' | ' . __FUNCTION__ );
458 }
459
460 $query = $this->wpdb->prepare(
461 "SELECT user_item_id FROM $this->tb_lp_user_items
462 WHERE item_id = %d
463 AND item_type = %s
464 ",
465 $filter->item_id,
466 LP_COURSE_CPT
467 );
468
469 return $this->wpdb->get_col( $query );
470 } catch ( Throwable $e ) {
471 error_log( __FUNCTION__ . ':' . $e->getMessage() );
472 return array();
473 }
474 }
475
476 /**
477 * Get items is course has user
478 *
479 * @param LP_User_Items_Filter $filter $filter->user_id, $filter->item_id
480 *
481 * @throws Exception
482 * @author tungnx
483 * @since 4.1.4
484 * @version 1.0.0
485 */
486 public function get_ids_course_user( LP_User_Items_Filter $filter ): array {
487 $query = $this->wpdb->prepare(
488 "SELECT user_item_id FROM $this->tb_lp_user_items
489 WHERE user_id = %d
490 AND item_id = %d
491 AND item_type = %s
492 ",
493 $filter->user_id,
494 $filter->item_id,
495 LP_COURSE_CPT
496 );
497
498 return $this->wpdb->get_col( $query );
499 }
500
501 /**
502 * Get items of course has user
503 *
504 * @param LP_User_Items_Filter $filter user_item_ids
505 *
506 * @throws Exception
507 * @since 4.1.4
508 * @version 1.0.0
509 */
510 public function get_item_ids_of_user_course( LP_User_Items_Filter $filter ): array {
511 if ( empty( $filter->user_item_ids ) ) {
512 return [];
513 }
514
515 $where = 'WHERE 1=1 ';
516
517 $where .= $this->wpdb->prepare(
518 'AND parent_id IN(' . LP_Helper::db_format_array( $filter->user_item_ids, '%d' ) . ')',
519 $filter->user_item_ids
520 );
521
522 return $this->wpdb->get_col(
523 "SELECT user_item_id FROM {$this->tb_lp_user_items}
524 {$where}
525 "
526 );
527 }
528
529 /**
530 * Remove rows IN user_item_ids
531 *
532 * @param LP_User_Items_Filter $filter $filter->user_item_ids, $filter->user_id
533 *
534 * @throws Exception
535 * @since 4.1.4
536 * @version 1.0.0
537 */
538 public function remove_user_item_ids( LP_User_Items_Filter $filter ) {
539 // Check valid user.
540 /*if ( ! is_user_logged_in() || ( ! current_user_can( ADMIN_ROLE ) && get_current_user_id() != $filter->user_id ) ) {
541 throw new Exception( __( 'User invalid!', 'learnpress' ) . ' | ' . __FUNCTION__ );
542 }*/
543
544 if ( empty( $filter->user_item_ids ) ) {
545 return 1;
546 }
547
548 $where = 'WHERE 1=1 ';
549
550 $where .= $this->wpdb->prepare(
551 'AND user_item_id IN(' . LP_Helper::db_format_array( $filter->user_item_ids, '%d' ) . ')',
552 $filter->user_item_ids
553 );
554
555 return $this->wpdb->query(
556 "DELETE FROM {$this->tb_lp_user_items}
557 {$where}
558 "
559 );
560 }
561
562 /**
563 * Remove user_itemmeta has list user_item_ids
564 *
565 * @param LP_User_Items_Filter $filter $filter->user_item_ids, $filter->user_id
566 *
567 * @throws Exception
568 * @since 4.1.4
569 * @version 1.0.0
570 */
571 public function remove_user_itemmeta( LP_User_Items_Filter $filter ) {
572 // Check valid user.
573 /*if ( ! is_user_logged_in() || ( ! current_user_can( ADMIN_ROLE ) && get_current_user_id() != $filter->user_id ) ) {
574 throw new Exception( __( 'User invalid!', 'learnpress' ) . ' | ' . __FUNCTION__ );
575 }*/
576
577 if ( empty( $filter->user_item_ids ) ) {
578 return 1;
579 }
580
581 $where = 'WHERE 1=1 ';
582
583 $where .= $this->wpdb->prepare(
584 'AND learnpress_user_item_id IN(' . LP_Helper::db_format_array( $filter->user_item_ids, '%d' ) . ')',
585 $filter->user_item_ids
586 );
587
588 return $this->wpdb->query(
589 "DELETE FROM {$this->tb_lp_user_itemmeta}
590 {$where}
591 "
592 );
593 }
594
595 /**
596 * Delete user_item_ids by user_id and course_id
597 *
598 * @param int $user_id
599 * @param int $course_id
600 * @author tungnx
601 * @since 4.1.4
602 * @version 1.0.0
603 */
604 public function delete_user_items_old( int $user_id = 0, int $course_id = 0 ) {
605 $lp_user_items_db = LP_User_Items_DB::getInstance();
606 $lp_user_item_results = LP_User_Items_Result_DB::instance();
607
608 try {
609 // Check valid user.
610 /*if ( ! is_user_logged_in() || ( ! current_user_can( ADMIN_ROLE ) && get_current_user_id() != $user_id ) ) {
611 throw new Exception( __( 'User invalid!', 'learnpress' ) . ' | ' . __FUNCTION__ );
612 }*/
613
614 // Get all user_item_ids has user_id and course_id
615 $filter = new LP_User_Items_Filter();
616 $filter->user_id = $user_id;
617 $filter->item_id = $course_id;
618
619 $user_course_ids = $lp_user_items_db->get_ids_course_user( $filter );
620
621 if ( empty( $user_course_ids ) ) {
622 return;
623 }
624
625 $course = learn_press_get_course( $course_id );
626 if ( ! $course ) {
627 return;
628 }
629
630 $course->delete_user_item_and_result( $user_course_ids );
631 } catch ( Throwable $e ) {
632 error_log( __FUNCTION__ . ': ' . $e->getMessage() );
633 }
634 }
635
636 /**
637 * Update user_id for lp_user_item with Order buy User Guest
638 *
639 * @param LP_User_Items_Filter $filter
640 *
641 * @return bool|int
642 * @throws Exception
643 */
644 public function update_user_id_by_order( LP_User_Items_Filter $filter ) {
645 // Check valid user.
646 if ( ! is_user_logged_in() || ( ! current_user_can( ADMIN_ROLE ) && get_current_user_id() != $filter->user_id ) ) {
647 throw new Exception( __FUNCTION__ . ': User invalid!' );
648 }
649
650 $query = $this->wpdb->prepare(
651 "UPDATE {$this->tb_lp_user_items}
652 SET user_id = %d
653 WHERE ref_type = %s
654 AND ref_id = %d
655 ",
656 $filter->user_id,
657 LP_ORDER_CPT,
658 $filter->ref_id
659 );
660
661 return $this->wpdb->query( $query );
662 }
663
664 /**
665 * Count items by type and total by status
666 * @throws Exception
667 *
668 * @return null|object
669 */
670 public function count_items_of_course_with_status( LP_User_Items_Filter $filter ) {
671 $item_types = learn_press_get_course_item_types();
672 $count_item_types = count( $item_types );
673 $i = 0;
674
675 //$user_course = $this->get_last_user_course( $filter );
676
677 $query_count = '';
678 $query_count .= $this->wpdb->prepare( 'SUM(ui.status = %s) AS count_status,', $filter->status );
679
680 foreach ( $item_types as $item_type ) {
681 $i++;
682 $query_count .= $this->wpdb->prepare( 'SUM(ui.status = %s AND ui.item_type = %s) AS %s,', $filter->status, $item_type, $item_type . '_status_' . $filter->status );
683 $query_count .= $this->wpdb->prepare( 'SUM(ui.graduation = %s AND ui.item_type = %s) AS %s', $filter->graduation, $item_type, $item_type . '_graduation_' . $filter->graduation );
684
685 if ( $i < $count_item_types ) {
686 $query_count .= ',';
687 }
688 }
689
690 $query = $this->wpdb->prepare(
691 'SELECT ' . $query_count . ' FROM ' . $this->tb_lp_user_items . ' ui
692 WHERE parent_id = %d
693 ',
694 $filter->parent_id
695 );
696
697 $total_items = $this->wpdb->get_row( $query );
698
699 return $total_items;
700 }
701
702 /**
703 * Get quizzes of user
704 *
705 * @param LP_User_Items_Filter $filter
706 *
707 * @return null|object
708 * @throws Exception
709 */
710 public function get_user_quizzes( LP_User_Items_Filter $filter ) {
711 @$this->wpdb->query( "SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))" );
712 $offset = ( absint( $filter->page ) - 1 ) * $filter->limit;
713
714 $WHERE = '';
715
716 if ( ! empty( $filter->graduation ) ) {
717 $WHERE .= $this->wpdb->prepare( 'AND graduation = %s ', $filter->graduation );
718 }
719
720 if ( ! empty( $filter->status ) ) {
721 $WHERE .= $this->wpdb->prepare( 'AND status = %s ', $filter->status );
722 }
723
724 $query = $this->wpdb->prepare(
725 "SELECT * FROM $this->tb_lp_user_items
726 WHERE user_item_id IN (
727 SELECT DISTINCT MAX(user_item_id)
728 FROM $this->tb_lp_user_items
729 WHERE user_id = %d
730 AND item_type = %s
731 AND status IN (%s, %s)
732 GROUP BY item_id
733 )
734 $WHERE
735 ORDER BY user_item_id DESC
736 LIMIT %d, %d
737 ",
738 $filter->user_id,
739 LP_QUIZ_CPT,
740 LP_ITEM_STARTED,
741 LP_ITEM_COMPLETED,
742 $offset,
743 $filter->limit
744 );
745
746 $result = $this->wpdb->get_results( $query );
747
748 $this->check_execute_has_error();
749
750 return $result;
751 }
752
753 /**
754 * Get courses only by course's user are learning
755 *
756 * @param LP_User_Items_Filter $filter
757 * @param int $total_rows
758 *
759 * @author tungnx
760 * @version 1.0.0
761 * @since 4.1.5
762 * @return null|array|string|int
763 * @throws Exception
764 */
765 public function get_user_courses( LP_User_Items_Filter $filter, int &$total_rows = 0 ) {
766 $default_fields = $this->get_cols_of_table( $this->tb_lp_user_items );
767 $filter->fields = array_merge( $default_fields, $filter->fields );
768
769 if ( empty( $filter->collection ) ) {
770 $filter->collection = $this->tb_lp_user_items;
771 }
772
773 if ( empty( $filter->collection_alias ) ) {
774 $filter->collection_alias = 'ui';
775 }
776
777 // Join to table posts check course exists
778 $filter->join[] = "INNER JOIN {$this->tb_posts} AS p ON p.ID = $filter->collection_alias.item_id";
779
780 // Get courses publish
781 $filter->where[] = $this->wpdb->prepare( 'AND p.post_status = %s', 'publish' );
782
783 $filter->where[] = $this->wpdb->prepare( "AND $filter->collection_alias.item_type = %s", LP_COURSE_CPT );
784
785 // Status
786 if ( $filter->status ) {
787 $filter->where[] = $this->wpdb->prepare( "AND $filter->collection_alias.status = %s", $filter->status );
788 }
789
790 // Graduation
791 if ( $filter->graduation ) {
792 $filter->where[] = $this->wpdb->prepare( "AND $filter->collection_alias.graduation = %s", $filter->graduation );
793 }
794
795 // User
796 if ( $filter->user_id ) {
797 $filter->where[] = $this->wpdb->prepare( "AND $filter->collection_alias.user_id = %d", $filter->user_id );
798 }
799
800 $filter = apply_filters( 'lp/user/course/query/filter', $filter );
801
802 return $this->execute( $filter, $total_rows );
803 }
804
805 /**
806 * Get total users attend courses of Author
807 *
808 * @param int $author_id
809 *
810 * @return LP_User_Items_Filter
811 * @since 4.1.6
812 * @version 1.0.0
813 * @throws Exception
814 */
815 public function count_user_attend_courses_of_author( int $author_id ): LP_User_Items_Filter {
816 $filter_course = new LP_Course_Filter();
817 $filter_course->only_fields = array( 'ID' );
818 $filter_course->post_author = $author_id;
819 $filter_course->post_status = 'publish';
820 $filter_course->return_string_query = true;
821 $query_courses_str = LP_Course_DB::getInstance()->get_courses( $filter_course );
822
823 $filter = new LP_User_Items_Filter();
824 $filter->item_type = LP_COURSE_CPT;
825 $filter->only_fields = array( 'DISTINCT (ui.user_id)' );
826 $filter->field_count = 'DISTINCT (ui.user_id)';
827 $filter->where[] = "AND item_id IN ({$query_courses_str})";
828 $filter->query_count = true;
829
830 return apply_filters( 'lp/user/course/query/filter/count-users-attend-courses-of-author', $filter );
831 }
832
833 /**
834 * Get list students attend
835 *
836 * @param LP_User_Items_Filter $filter
837 * @param int $total_rows
838 *
839 * @return array|int|string|null
840 * @since 4.1.6.9
841 * @throws Exception
842 */
843 public function get_students( LP_User_Items_Filter $filter, int &$total_rows = 0 ) {
844 $default_fields = $this->get_cols_of_table( $this->tb_users );
845 $filter->fields = array_merge( $default_fields, $filter->fields );
846 $filter->exclude_fields = [ 'user_pass', 'user_login', 'user_status', 'user_activation_key' ];
847 $filter->field_count = 'ID';
848
849 if ( empty( $filter->collection ) ) {
850 $filter->collection = $this->tb_users;
851 }
852
853 if ( empty( $filter->collection_alias ) ) {
854 $filter->collection_alias = 'u';
855 }
856
857 // Filter
858 $filter->join[] = "INNER JOIN $this->tb_lp_user_items AS ui ON u.ID = ui.user_id";
859 $filter->where[] = $this->wpdb->prepare( 'AND item_type =%s', LP_COURSE_CPT );
860
861 // Filter by user ids
862 if ( ! empty( $filter->user_ids ) ) {
863 $term_ids_format = LP_Helper::db_format_array( $filter->user_ids, '%d' );
864 $filter->where[] = $this->wpdb->prepare( 'AND r_term.term_taxonomy_id IN (' . $term_ids_format . ')', $filter->user_ids );
865 }
866
867 // Filter
868
869 $filter->group_by = 'ID';
870
871 // End filter
872
873 $filter = apply_filters( 'lp/course/query/students', $filter );
874
875 return $this->execute( $filter, $total_rows );
876 }
877 }
878
879 LP_Course_DB::getInstance();
880
881