PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.1
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / inc / 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.4.1, at inc/Databases/class-lp-user-items-db.php

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