PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.2.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.2.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 / user / abstract-lp-user.php

abstract-lp-user.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.2.1, at inc/user/abstract-lp-user.php

1,432 lines 34.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_Abstract_User
5 *
6 * @author ThimPress
7 * @package LearnPress/Classes
8 * @version 3.0.0
9 */
10
11 /**
12 * Prevent loading this file directly
13 */
14 defined( 'ABSPATH' ) || exit();
15
16 if ( ! class_exists( 'LP_Abstract_User' ) ) {
17
18 /**
19 * Class LP_Abstract_User
20 */
21 class LP_Abstract_User extends LP_Abstract_Object_Data {
22
23 /**
24 * @var WP_User object
25 */
26 public $user = false;
27
28 /**
29 * @var null
30 */
31 public $profile_picture_src = null;
32
33 /**
34 * @var null
35 */
36 public $profile_picture_type = null;
37
38 /**
39 * @var array
40 */
41 protected $_data = array(
42 'email' => '',
43 'user_login' => '',
44 'description' => '',
45 'first_name' => '',
46 'last_name' => '',
47 'nickname' => '',
48 'display_name' => '',
49 'date_created' => '',
50 'date_modified' => '',
51 'role' => '',
52 'roles' => array(),
53 );
54
55 /**
56 * @var LP_User_CURD
57 */
58 protected $_curd = null;
59
60 /**
61 * LP_Abstract_User constructor.
62 *
63 * @param int $the_user
64 * @param array $args
65 */
66 public function __construct( $the_user = 0, $args = array() ) {
67
68 parent::__construct( $the_user, $args );
69
70 $this->_curd = new LP_User_CURD();
71
72 if ( is_numeric( $the_user ) && $the_user > 0 ) {
73 $this->set_id( $the_user );
74 } elseif ( $the_user instanceof self ) {
75 $this->set_id( absint( $the_user->get_id() ) );
76 } elseif ( ! empty( $the_user->ID ) ) {
77 $this->set_id( absint( $the_user->ID ) );
78 }
79
80 if ( $this->get_id() > 0 ) {
81 $this->load();
82 }
83
84 }
85
86 /**
87 * Load user data from curd
88 */
89 public function load() {
90 $this->_curd->load( $this );
91 }
92
93 /**
94 * Get data for a course user has enrolled.
95 *
96 * @param int $course_id .
97 *
98 * @return LP_User_Item_Course|bool
99 * @version 3.1.3
100 * @editor tungnx
101 * @modify 4.1.3
102 */
103 public function get_course_data( int $course_id = 0 ) {
104 $lp_user_items_db = LP_User_Items_DB::getInstance();
105 $object_course_data = false;
106
107 try {
108 if ( ! $course_id ) {
109 $course_id = get_the_ID();
110 }
111
112 /*if ( $this instanceof LP_User_Guest ) {
113 throw new Exception( 'User is Guest' );
114 }*/
115
116 $filter = new LP_User_Items_Filter();
117 $filter->item_id = $course_id;
118 $filter->user_id = $this->get_id();
119 $last_user_course = $lp_user_items_db->get_last_user_course( $filter );
120
121 if ( $last_user_course ) {
122 $object_course_data = new LP_User_Item_Course( $last_user_course );
123 } else {
124 $object_course_data = false;
125 /**
126 * Todo: some themes still not check false, so still use below code.\
127 * @editor tungnx 4.1.6.9
128 */
129 $object_course_data = new LP_User_Item_Course( $course_id );
130 }
131 } catch ( Throwable $e ) {
132 $object_course_data = false;
133 }
134
135 return $object_course_data;
136 }
137
138 /**
139 * Get user course item.
140 *
141 * @param int $item_id
142 * @param int $course_id
143 * @param string $field - Optional. Value of field to return.
144 *
145 * @return LP_User_Item_Quiz|LP_User_Item|bool
146 */
147 public function get_item_data( $item_id, $course_id, $field = '' ) {
148 $user_item = $this->get_user_item( $item_id, $course_id );
149
150 switch ( $field ) {
151 case 'end_time':
152 return $user_item->get_end_time();
153 }
154
155 return $user_item;
156 }
157
158 /**
159 * Get data for a item user started in table user-items
160 *
161 * @param int $item_id
162 * @param int $course_id
163 *
164 * @return LP_User_Item_Quiz|LP_User_Item|bool
165 */
166 public function get_user_item( $item_id, $course_id ) {
167 $data = false;
168
169 $course_data = $this->get_course_data( $course_id );
170
171 if ( $course_data ) {
172 $data = $course_data->get_item( $item_id );
173 }
174
175 return $data;
176 }
177
178 /**
179 * Return TRUE if user has used function for checking the question.
180 *
181 * @param int $question_id
182 * @param int $quiz_id
183 * @param int $course_id
184 *
185 * @return mixed
186 * @since 3.0.0
187 */
188 public function has_checked_question( $question_id, $quiz_id, $course_id = 0 ) {
189 $checked = false;
190
191 if ( $this->get_quiz_data( $quiz_id, $course_id ) ) {
192 $data = $this->get_quiz_data( $quiz_id, $course_id );
193 $checked = $data->has_checked_question( $question_id );
194 }
195
196 return apply_filters(
197 'learn-press/user/checked-question',
198 $checked,
199 $question_id,
200 $quiz_id,
201 $course_id,
202 $this->get_id()
203 );
204 }
205
206 /**
207 * Magic function to get user data
208 *
209 * @param $key
210 *
211 * @return bool
212 */
213 public function __get( $key ) {
214 $return = false;
215
216 if ( strtolower( $key ) !== 'id' ) {
217 _deprecated_argument( __CLASS__ . '::' . $key, '3.0.0' );
218 }
219
220 if ( ! empty( $this->user->data->{$key} ) ) {
221 $return = $this->user->data->{$key};
222 } else {
223 if ( isset( $this->{$key} ) ) {
224 $return = $this->{$key};
225 } elseif ( strpos( $key, '_lp_' ) === false ) {
226 $key = '_lp_' . $key;
227 $return = get_user_meta( $this->get_id(), $key, true );
228 if ( ! empty( $value ) ) {
229 $this->$key = $return;
230 }
231 }
232 }
233
234 return $return;
235 }
236
237 /**
238 * Check if a course is exists then return it's ID.
239 * Try to get it from global.
240 *
241 * @param int $course_id
242 * @param string $return
243 *
244 * @return bool|false|int|LP_Course
245 */
246 protected function _get_course( $course_id, $return = 'id' ) {
247
248 // if $course_id is not passed then try to get it from global
249 if ( ! $course_id && learn_press_is_course() ) {
250 $course_id = get_the_ID();
251 }
252
253 // Validate course
254 $course = learn_press_get_course( $course_id );
255
256 if ( $course ) {
257 switch ( $return ) {
258 case 'id':
259 return $course_id;
260 case 'object':
261 return $course;
262 }
263 }
264
265 return false;
266 }
267
268 /**
269 *
270 * @param int $item_id
271 * @param int $course_id
272 *
273 * @return bool
274 *
275 * @since 3.0.0
276 */
277 protected function _verify_course_item( $item_id, $course_id = 0 ) {
278 $course = $this->_get_course( $course_id, 'object' );
279
280 if ( false !== $course ) {
281 return $course->has_item( $item_id ) ? $course_id : false;
282 }
283
284 return false;
285 }
286
287 /**
288 * Return TRUE if an item has a status.
289 *
290 * @param array $statuses
291 * @param int $item_id
292 * @param int $course_id
293 *
294 * @return mixed
295 *
296 * @since 3.0.0
297 */
298 public function has_item_status( $statuses, $item_id, $course_id ) {
299 settype( $statuses, 'array' );
300 $status = $this->get_item_status( $item_id, $course_id );
301
302 //Todo: tungnx
303 //$status = $this->getItemStatus( $item_id, $course_id );
304
305 return apply_filters(
306 'learn-press/user-has-item-status',
307 in_array( $status, $statuses ),
308 $statuses,
309 $item_id,
310 $course_id,
311 $this->get_id()
312 );
313 }
314
315 /**
316 * Get all records of an item.
317 *
318 * @param int $item_id
319 * @param int $course_id
320 * @param bool $return_last
321 *
322 * @return bool|mixed
323 */
324 public function get_item_archive( $item_id, $course_id = 0, $return_last = false ) {
325 $records = LP_Object_Cache::get(
326 'course-item-' . $this->get_id() . '-' . $course_id . '-' . $item_id,
327 'lp-user-course-items'
328 );
329
330 if ( $records ) {
331 // $records = array_filter( $records );
332 }
333
334 if ( $return_last && is_array( $records ) ) {
335 $records = reset( $records );
336 }
337
338 return $records;
339 }
340
341 /**
342 * Check quiz can retake?
343 *
344 * @param [type] $quiz_id
345 * @param [type] $course_id
346 *
347 * @return boolean
348 */
349 public function has_retake_quiz( $quiz_id, $course_id ): bool {
350 $user_quiz = $this->get_item_data( $quiz_id, $course_id );
351 $flag = false;
352
353 if ( $user_quiz ) {
354 $retaken = $user_quiz->get_retaken_count();
355 $retake_config = get_post_meta( $quiz_id, '_lp_retake_count', true );
356
357 if ( $retake_config == '-1' ) { // For no limit
358 $flag = true;
359 } elseif ( absint( $retaken ) < absint( $retake_config ) ) {
360 $flag = true;
361 }
362 }
363
364 return apply_filters( 'lp/quiz/can-retake', $flag );
365 }
366
367 /**
368 * Get quiz status for the user
369 *
370 * @param int $quiz_id
371 * @param int $course_id
372 *
373 * @return mixed
374 */
375 public function get_quiz_status( $quiz_id, $course_id = 0 ) {
376 return $this->get_item_status( $quiz_id, $course_id );
377 }
378
379 /**
380 * Get quiz status for the user
381 *
382 * @param int $lesson_id
383 * @param int $course_id
384 *
385 * @return mixed
386 */
387 public function get_lesson_status( $lesson_id, $course_id = 0 ) {
388 return $this->get_item_status( $lesson_id, $course_id );
389 }
390
391 /**
392 * @param int $item_id
393 * @param int $course_id
394 * @param bool $last
395 *
396 * @return mixed
397 * @since 3.0.0
398 */
399 public function get_item( $item_id, $course_id = 0, $last = false ) {
400 if ( ! $course_id ) {
401 $course_id = get_the_ID();
402 }
403
404 if ( ! $course_id ) {
405 return false;
406 }
407
408 $course_data = $this->get_course_data( $course_id );
409 if ( $course_data ) {
410 return $course_data->get_item( $item_id );
411 }
412
413 return false;
414 }
415
416 /**
417 * @param int $item_id
418 * @param int $course_id
419 *
420 * @return mixed
421 * @since 3.0.0
422 * @version 1.0.1
423 * @editor tungnx
424 * @modify 4.1.4.1
425 */
426 public function get_item_grade( $item_id, $course_id = 0 ) {
427 if ( ! $course_id ) {
428 $course_id = get_the_ID();
429 }
430
431 $grade = false;
432
433 $course_data = $this->get_course_data( $course_id );
434
435 if ( $course_data ) {
436 $grade = $course_data->get_item_result( $item_id, 'grade' );
437 }
438
439 return apply_filters( 'learn-press/user-item-grade', $grade, $item_id, $this->get_id(), $course_id );
440 }
441
442 /**
443 * Get current status of an item for user.
444 *
445 * @param int $item_id
446 * @param int $course_id
447 *
448 * @return bool|mixed
449 */
450 public function get_item_status( $item_id, $course_id = 0 ) {
451 $status = '';
452
453 if ( ! $course_id ) {
454 $course_id = get_the_ID();
455 if ( ! $course_id ) {
456 return $status;
457 }
458 }
459
460 $item = $this->get_item( $item_id, $course_id, true );
461 if ( $item instanceof LP_User_Item ) {
462 $status = $item->get_status();
463 }
464
465 return apply_filters( 'learn-press/user-item-status', $status, $item_id, $this->get_id(), $course_id );
466 }
467
468 /**
469 * Checks if has status of a quiz for user
470 *
471 * @param string|array $statuses
472 * @param int $quiz_id
473 * @param int $course_id
474 * @param boolean $force
475 *
476 * @return bool
477 */
478 public function has_quiz_status( $statuses, $quiz_id, $course_id = 0, $force = false ) {
479 $status = $this->get_quiz_status( $quiz_id, $course_id );
480
481 settype( $statuses, 'array' );
482
483 return apply_filters(
484 'learn_press_user_has_quiz_status',
485 in_array( $status, $statuses ),
486 $statuses,
487 $status,
488 $quiz_id,
489 $course_id,
490 $this->get_id()
491 );
492 }
493
494 /**
495 * Get current results of a quiz
496 *
497 * @param int $quiz_id
498 * @param int $course_id
499 * @param string $prop
500 *
501 * @return mixed
502 */
503 public function get_quiz_results( $quiz_id, $course_id = 0, $prop = 'result' ) {
504 $user_quiz = $this->get_item_data( $quiz_id, $course_id );
505
506 return $user_quiz ? $user_quiz->get_results( $prop ) : false;
507 }
508
509 /**
510 * Get current progress of user's quiz.
511 *
512 * @param int $quiz_id
513 * @param int $course_id
514 *
515 * @return LP_User_Item_Quiz|false
516 */
517 public function get_quiz_data( $quiz_id, $course_id = 0 ) {
518 $result = false;
519 $course_result = $this->get_course_data( $course_id );
520 if ( $course_result ) {
521 $result = $course_result->get_item( $quiz_id );
522 }
523
524 return $result;
525 }
526
527 /**
528 * Mark question that user has checked.
529 *
530 * @param int $question_id
531 * @param int $quiz_id
532 * @param int $course_id
533 *
534 * @return WP_Error|mixed
535 * @since 3.0.0
536 */
537 public function hint( $question_id, $quiz_id, $course_id ) {
538 $course = learn_press_get_course( $course_id );
539 if ( ! $course ) {
540 return false;
541 }
542
543 if ( ! $course->has_item( $quiz_id ) ) {
544 return false;
545 }
546
547 /**
548 * @var $quiz LP_Quiz
549 */
550 $quiz = $course->get_item( $quiz_id );
551 if ( ! $quiz instanceof LP_Course_Item_Quiz ) {
552 return false;
553 }
554
555 if ( ! $quiz->has_question( $question_id ) ) {
556 return false;
557 }
558
559 $quiz_data = $this->get_item_data( $quiz_id, $course_id );
560 $remain = $quiz_data->hint( $question_id );
561 if ( false === $remain ) {
562 return new WP_Error( 1001, __( 'You can not hint at the question.', 'learnpress' ) );
563 }
564
565 return $remain;
566 }
567
568 public function get_quiz_last_results( $quiz_id ) {
569 $results = $this->get_course_info( $quiz_id );
570 if ( $results ) {
571 $results = reset( $results );
572 }
573
574 return apply_filters( 'learn_press_user_quiz_last_results', $results, $quiz_id, $this );
575 }
576
577 /**
578 * Check if user has at least one role.
579 *
580 * @param array|string $roles
581 *
582 * @return array
583 */
584 public function has_role( $roles ) {
585 settype( $roles, 'array' );
586
587 return array_intersect( $roles, $this->get_roles() );
588 }
589
590 /**
591 * Detect the type of user
592 *
593 * @param string|int $type
594 *
595 * @return bool
596 */
597 public function is( $type ) {
598 $is = false;
599 if ( $type === 'current' ) {
600 $is = $this->is( get_current_user_id() );
601 } elseif ( is_string( $type ) ) {
602 $name = preg_replace( '!LP_User(_?)!', '', get_class( $this ) );
603 $is = strtolower( $name ) == strtolower( $type );
604 } elseif ( is_numeric( $type ) ) {
605 $is = $this->get_id() && ( $this->get_id() == $type );
606 }
607
608 return $is;
609 }
610
611 /**
612 *
613 * Check what the user can do
614 *
615 * @param $role
616 *
617 * @return mixed
618 * @throws Exception
619 */
620 public function can( $role ) {
621 _deprecated_function( __FUNCTION__, '3.0.8' );
622 $args = func_get_args();
623 unset( $args[0] );
624 $method = 'can_' . preg_replace( '!-!', '_', $role );
625 $callback = array( $this, $method );
626 if ( is_callable( $callback ) ) {
627 return call_user_func_array( $callback, $args );
628 } else {
629 throw new Exception( sprintf( __( 'The role %s for the user doesn\'t exist', 'learnpress' ), $role ) );
630 }
631 }
632
633 public function can_edit_item( $item_id, $course_id = 0 ) {
634 $return = $this->is_admin();
635
636 if ( ! $return ) {
637 $course_id = $this->_get_course( $course_id );
638
639 $course_author = learn_press_get_course_user( $course_id );
640 if ( $course_author && $course_author->get_id() == $this->get_id() ) {
641 $return = true;
642 }
643 }
644
645 return apply_filters( 'learn_press_user_can_edit_item', $return, $item_id, $course_id, $this->get_id() );
646 }
647
648 /**
649 * Check if user can finish course by getting current progress
650 * and compares with course passing condition.
651 *
652 * @param int $course_id
653 *
654 * @return bool
655 * @editor tungnx
656 * @modify 4.1.3
657 */
658 public function can_finish_course( int $course_id ) {
659 _deprecated_function( __FUNCTION__, '4.1.3', 'is_course_finished' );
660
661 return true;
662 }
663
664 /**
665 * Check if course has any passed status for an user.
666 * Statuses: depending on value of column `status` in user_items.
667 * - purchased: bought and order is completed, `start_date` and `end_date` is null
668 * - enrolled: value of column `status` in user_items is enrolled
669 * - started: value of column `status` in user_items is started
670 * - enrolled: value of column `status` in user_items is enrolled
671 *
672 * @param int $course_id
673 * @param string|array $statuses
674 *
675 * @return bool
676 * @since 2.0
677 */
678 public function has_course_status( $course_id, $statuses ) {
679 $status = $this->get_course_status( $course_id );
680
681 if ( is_array( $statuses ) ) {
682 return in_array( $status, $statuses );
683 } elseif ( is_string( $statuses ) ) {
684 return $statuses == $status;
685 }
686
687 return false;
688 }
689
690 /**
691 * Finish course
692 *
693 * @param int $course_id
694 *
695 * @return int|bool
696 */
697 public function finish_course( int $course_id ) {
698 $return = false;
699 $course = learn_press_get_course( $course_id );
700
701 if ( $course ) {
702 $user_course = $this->get_course_data( $course_id );
703 if ( ! $user_course ) {
704 return $return;
705 }
706
707 $result = $user_course->calculate_course_results();
708
709 // Save result for course
710 LP_User_Items_Result_DB::instance()->update( $user_course->get_user_item_id(), wp_json_encode( $result ) );
711
712 if ( $result['pass'] ) {
713 $graduation = LP_COURSE_GRADUATION_PASSED;
714 } else {
715 $graduation = LP_COURSE_GRADUATION_FAILED;
716 }
717
718 $user_course->set_graduation( $graduation );
719 //$user_course->save();
720 $return = $user_course->complete( LP_COURSE_FINISHED );
721
722 if ( $return ) {
723 do_action( 'learn-press/user-course-finished', $course_id, $this->get_id(), $return );
724 }
725 }
726
727 return apply_filters( 'learn-press/user-course-finished-data', $return, $course_id, $this->get_id() );
728 }
729
730 /**
731 * Check user instructor.
732 *
733 * @return bool
734 */
735 public function is_instructor(): bool {
736
737 $roles = $this->get_data( 'roles' ) ? $this->get_data( 'roles' ) : array();
738
739 return in_array( LP_TEACHER_ROLE, $roles );
740 }
741
742 /**
743 * Check user admin.
744 *
745 * @return bool
746 */
747 public function is_admin() {
748 $roles = $this->get_data( 'roles' ) ? $this->get_data( 'roles' ) : array();
749
750 return in_array( 'administrator', $roles );
751 }
752
753
754 public function can_create_course() {
755 return $this->is_instructor() || $this->is_admin();
756 }
757
758 /**
759 * Wrap function to check this user is author of a post.
760 *
761 * @param int $post_id
762 *
763 * @return bool
764 * @since 3.1.0
765 */
766 public function is_author_of( $post_id ) {
767 return absint( get_post_field( 'post_author', $post_id ) ) === $this->get_id();
768 }
769
770 public function has( $role ) {
771 _deprecated_function( __FUNCTION__, '3.0.8' );
772
773 $args = func_get_args();
774 unset( $args[0] );
775 $method = 'has_' . preg_replace( '!-!', '_', $role );
776 $callback = array( $this, $method );
777 if ( is_callable( $callback ) ) {
778 return call_user_func_array( $callback, $args );
779 } else {
780 throw new Exception( sprintf( __( 'The role %s for the user doesn\'t exist', 'learnpress' ), $role ) );
781 }
782 }
783
784 public function get( $role ) {
785 $args = func_get_args();
786 unset( $args[0] );
787 $method = 'get_' . preg_replace( '!-!', '_', $role );
788 $callback = array( $this, $method );
789 if ( is_callable( $callback ) ) {
790 return call_user_func_array( $callback, $args );
791 } else {
792 throw new Exception( sprintf( __( 'The role %s for the user doesn\'t exist', 'learnpress' ), $role ) );
793 }
794 }
795
796 /**
797 * Check user has passed course.
798 *
799 * @param $course_id
800 *
801 * @return mixed
802 */
803 public function has_passed_course( $course_id ) {
804 $user_course = $this->get_course_data( $course_id );
805
806 return $user_course && $user_course->is_passed();
807 }
808
809 /**
810 * Checks if user has started a quiz
811 * - FALSE if user has not started quiz
812 * - String if user has started quiz (status of quiz)
813 *
814 * @param int $quiz_id
815 * @param int $course_id
816 *
817 * @return mixed
818 */
819 public function has_started_quiz( $quiz_id, $course_id = 0 ) {
820 $course_id = $this->_get_course( $course_id );
821 $started = false;
822 $started = $this->has_quiz_status( array( 'started', 'completed' ), $quiz_id, $course_id );
823
824 return apply_filters( 'learn_press_user_started_quiz', $started, $quiz_id, $course_id, $this->get_id() );
825 }
826
827 /**
828 * Return true if user has completed a quiz
829 *
830 * @param int $quiz_id
831 * @param int $course_id
832 *
833 * @return bool
834 * @deprecated 4.1.6.9
835 */
836 /*public function has_completed_quiz( $quiz_id, $course_id = 0 ): bool {
837 return $this->get_item_status( $quiz_id, $course_id ) == 'completed';
838 }*/
839
840 /**
841 * Mark a lesson is completed for user
842 *
843 * @param int $lesson_id
844 * @param int $course_id
845 *
846 * @return bool|WP_Error
847 */
848 public function complete_lesson( $lesson_id = 0, $course_id = 0 ) {
849 $result = true;
850
851 try {
852 $course = learn_press_get_course( $course_id );
853 if ( ! $course ) {
854 throw new Exception( __( 'Invalid course', 'learnpress' ) );
855 }
856
857 $course_data = $this->get_course_data( $course_id );
858 if ( ! $course_data ) {
859 throw new Exception( __( 'You must enroll course!', 'learnpress' ) );
860 }
861
862 /**
863 * If user has stared a lesson, get user lesson information
864 */
865 $item = $course_data->get_item( $lesson_id );
866 if ( ! $item ) {
867 throw new Exception( __( 'Invalid lesson', 'learnpress' ) );
868 }
869
870 if ( $item->is_completed() ) {
871 throw new Exception( __( 'You have already completed this lesson.', 'learnpress' ) );
872 }
873
874 $item->set_graduation( 'passed' );
875 $updated = $item->complete();
876
877 do_action( 'learn-press/user-completed-lesson', $lesson_id, $course_id, $this->get_id() );
878 } catch ( Throwable $e ) {
879 $result = new WP_Error( 'error_lesson_complete', $e->getMessage() );
880 }
881
882 return $result;
883 }
884
885 /**
886 * Returns TRUE if user has already completed a lesson
887 *
888 * @param int $lesson_id Lesson id.
889 * @param null $course_id Course id.
890 *
891 * @return bool
892 * @deprecated 4.1.6.9
893 */
894 public function has_completed_lesson( $lesson_id = 0, $course_id = null ): bool {
895 return 'completed' === $this->get_item_status( $lesson_id, $course_id );
896 }
897
898 /**
899 * Return current status of course for user
900 *
901 * @param int $course_id
902 * @param string $field
903 * @param bool $force
904 *
905 * @return mixed
906 */
907 public function get_course_info( int $course_id, $field = null, $force = false ) {
908 $user_data = $this->get_course_data( $course_id );
909 if ( $user_data ) {
910 return $user_data->get_results( $field );
911 }
912
913 return false;
914 }
915
916 /**
917 * @param $course_id
918 *
919 * @return int
920 * @deprecated 4.1.6.9
921 */
922 public function get_course_history_id( $course_id ) {
923 $history = $this->get_course_info( $course_id );
924
925 return ! empty( $history['history_id'] ) ? $history['history_id'] : 0;
926 }
927
928 /**
929 * Get current status of a course for user.
930 *
931 * @param int $course_id
932 *
933 * @return mixed
934 * @editor tungnx
935 * @modify 4.1.3
936 * @version 1.0.1
937 */
938 public function get_course_status( int $course_id ): string {
939 $status = '';
940
941 try {
942 $user_data = $this->get_course_data( $course_id );
943
944 if ( $user_data ) {
945 $status = $user_data->get_status();
946 }
947 } catch ( Throwable $e ) {
948 if ( LP_Debug::is_debug() ) {
949 error_log( $e->getMessage() );
950 }
951 }
952
953 return apply_filters( 'learn-press/user-course-status', $status, $course_id, $this->get_id() );
954 }
955
956 /**
957 * Get order status of a course.
958 *
959 * @param int $course_id
960 *
961 * @return mixed
962 */
963 public function get_order_status( $course_id ) {
964 try {
965 $order = $this->get_course_order( $course_id );
966
967 if ( ! $order ) {
968 throw new Exception( 'Order not exists' );
969 }
970
971 $order_status = apply_filters(
972 'learn-press/course-order-status',
973 get_post_status( $order->get_id() ),
974 $course_id,
975 $this->get_id()
976 );
977 } catch ( Throwable $e ) {
978 $order_status = false;
979 }
980
981 return $order_status;
982 }
983
984 /**
985 * Check item completed.
986 *
987 * @param $item
988 * @param int $course_id
989 * @param bool $force
990 *
991 * @return mixed|void
992 * @version 3.0.1
993 * @since 3.0.0
994 */
995 public function has_completed_item( $item, $course_id = 0, $force = false ) {
996 $course_id = $this->_get_course( $course_id );
997
998 $return = false;
999 $item_id = 0;
1000 if ( is_numeric( $item ) ) {
1001 $item_id = absint( $item );
1002 } else {
1003 settype( $item, 'array' );
1004 if ( ! empty( $item['ID'] ) ) {
1005 $item_id = absint( $item['ID'] );
1006 }
1007 }
1008
1009 if ( $item_id ) {
1010 $return = 'completed' === $this->get_item_status( $item_id, $course_id );
1011 }
1012
1013 return apply_filters( 'learn_press_user_has_completed_item', $return, $item );
1014 }
1015
1016 /**
1017 * Get the remaining time of a course for the user.
1018 *
1019 * @param int $course_id
1020 *
1021 * @return bool|int|string
1022 * @deprecated 4.1.7.3
1023 */
1024 public function get_course_remaining_time( $course_id ) {
1025 _deprecated_function( __FUNCTION__, '4.1.7.3' );
1026 /*$course = learn_press_get_course( $course_id );
1027 $remain = false;
1028
1029 if ( $course && $course->get_id() ) {
1030 $course_data = $this->get_course_data( $course_id, true );
1031 if ( $course_data ) {
1032 $remain = $course_data->is_exceeded();
1033 }
1034 }
1035
1036 return $remain > 0 ? learn_press_seconds_to_weeks( $remain ) : false;*/
1037 }
1038
1039 /**
1040 * Get the order that contains the course.
1041 *
1042 * @param int $course_id
1043 *
1044 * @return bool|LP_Order
1045 * @editor tungnx
1046 * @throws Exception
1047 * @version 1.0.2
1048 * @since 4.1.1
1049 */
1050 public function get_course_order( int $course_id ) {
1051 $lp_order = false;
1052 $lp_order_db = LP_Order_DB::getInstance();
1053 $lp_order_id = $lp_order_db->get_last_lp_order_id_of_user_course( $this->get_id(), $course_id );
1054
1055 if ( $lp_order_id ) {
1056 $lp_order = new LP_Order( $lp_order_id );
1057 }
1058
1059 return $lp_order;
1060 }
1061
1062 /**
1063 * @param $question_id
1064 *
1065 * @return null|string
1066 */
1067 public function get_quiz_by_question( $question_id ) {
1068 global $wpdb;
1069 $query = $wpdb->prepare(
1070 "
1071 SELECT quiz_id
1072 FROM {$wpdb->prefix}learnpress_user_items uq
1073 INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta uqm ON uqm.learnpress_user_item_id = uq.user_item_id AND uqm.meta_key = %s AND uqm.meta_value LIKE %s
1074 ",
1075 'questions',
1076 '%i:' . $wpdb->esc_like( $question_id . '' ) . ';%'
1077 );
1078
1079 return $wpdb->get_var( $query );
1080 }
1081
1082 /**
1083 * @param $question_id
1084 * @param null $quiz_id
1085 *
1086 * @return bool
1087 */
1088 public function get_answer_results( $question_id, $quiz_id = null ) {
1089
1090 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '3.0.0' );
1091
1092 $data = false;
1093 if ( ! $quiz_id ) {
1094 $quiz_id = $this->get_quiz_by_question( $question_id );
1095 }
1096 if ( $quiz_id ) {
1097 $question = LP_Question::get_question( $question_id );
1098
1099 if ( $question ) {
1100 $quiz_results = $this->get_quiz_results( $quiz_id );
1101 if ( ! empty( $quiz_results->question_answers ) ) {
1102 $question_answer = array_key_exists(
1103 $question_id,
1104 $quiz_results->question_answers
1105 ) ? $quiz_results->question_answers[ $question_id ] : null;
1106 $data = $question->check( $question_answer );
1107 }
1108 }
1109 }
1110
1111 return $data;
1112 }
1113
1114 /**
1115 * @param $question_id
1116 * @param null $quiz_id
1117 *
1118 * @return bool
1119 */
1120 public function is_answered_question( $question_id, $quiz_id = null ) {
1121 if ( empty( $this->answered_questions ) ) {
1122 $this->answered_questions = array();
1123 }
1124 if ( ! $quiz_id ) {
1125 $quiz_id = $this->get_quiz_by_question( $question_id );
1126 }
1127
1128 $results = $this->get_quiz_results( $quiz_id );
1129 $answered = ! empty( $results->question_answers ) ? $results->question_answers : array();
1130
1131 return $answered ? array_key_exists( $question_id, $answered ) : false;
1132 }
1133
1134 /**
1135 * @return array
1136 */
1137 public function get_roles() {
1138 return (array) $this->get_data( 'roles' );
1139 }
1140
1141 /**
1142 * @param $question_id
1143 * @param $quiz_id
1144 * @param int $course_id
1145 *
1146 * @return bool
1147 */
1148 public function has_checked_answer( $question_id, $quiz_id, $course_id = 0 ) {
1149 if ( ! $course_id ) {
1150 $course_id = get_the_ID();
1151 }
1152
1153 $quiz_data = $this->get_item_data( $quiz_id, $course_id );
1154
1155 return $quiz_data ? $quiz_data->has_checked_question( $question_id ) : false;
1156 }
1157
1158 /**
1159 * @param $question_id
1160 * @param $quiz_id
1161 * @param int $course_id
1162 *
1163 * @return bool
1164 */
1165 public function has_hinted_answer( $question_id, $quiz_id, $course_id = 0 ) {
1166 if ( ! $course_id ) {
1167 $course_id = get_the_ID();
1168 }
1169
1170 $quiz_data = $this->get_item_data( $quiz_id, $course_id );
1171
1172 return $quiz_data ? $quiz_data->has_hinted_question( $question_id ) : false;
1173 }
1174
1175 /**
1176 * Return TRUE if user is already exists.
1177 *
1178 * @return bool
1179 */
1180 public function is_exists() {
1181 return ! ! get_user_by( 'id', $this->get_id() );
1182 }
1183
1184 /**
1185 * Check if the user is logged in.
1186 *
1187 * @return bool
1188 */
1189 public function is_logged_in() {
1190 return $this->get_id() == get_current_user_id();
1191 }
1192
1193 /**
1194 * Get upload profile src
1195 * Option: null: get origin picture, "thumbnail": get thumbnail picture
1196 *
1197 * @param mixed $size
1198 *
1199 * @return string
1200 */
1201 public function get_upload_profile_src( $size = '' ) {
1202 return LP_Profile::instance( $this->get_id() )->get_upload_profile_src( $size );
1203 }
1204
1205 /**
1206 * @param string $type
1207 * @param int $size
1208 * @param bool $src_only
1209 *
1210 * @return false|string
1211 */
1212 public function get_profile_picture( $type = '', $size = 96, $src_only = false ) {
1213 return LP_Profile::instance( $this->get_id() )->get_profile_picture( $type, $size );
1214 }
1215
1216 /**
1217 * Get links socials of use on Profile page
1218 *
1219 * @param int $user_id
1220 * @return array
1221 */
1222 public function get_profile_socials( int $user_id = 0 ): array {
1223 $socials = array();
1224 $extra_info = learn_press_get_user_extra_profile_info( $user_id );
1225
1226 if ( $extra_info ) {
1227 foreach ( $extra_info as $k => $v ) {
1228 if ( empty( $v ) ) {
1229 continue;
1230 }
1231
1232 switch ( $k ) {
1233 case 'facebook':
1234 $i = '<i class="fab fa-facebook-f"></i>';
1235 break;
1236 case 'twitter':
1237 $i = '<i class="fab fa-twitter"></i>';
1238 break;
1239 case 'googleplus':
1240 $i = '<i class="fab fa-google-plus-g"></i>';
1241 break;
1242 case 'youtube':
1243 $i = '<i class="fab fa-youtube"></i>';
1244 break;
1245 default:
1246 $i = sprintf( '<i class="fab fa-%s"></i>', $k );
1247 }
1248
1249 $icon = apply_filters(
1250 'learn-press/user-profile-social-icon',
1251 $i,
1252 $k,
1253 $this->get_id(),
1254 $this
1255 );
1256 $socials[ $k ] = sprintf( '<a href="%s">%s</a>', esc_url_raw( $v ), $icon );
1257 }
1258 }
1259
1260 return apply_filters( 'learn-press/user-profile-socials', $socials, $this->get_id(), $this );
1261 }
1262
1263 /**
1264 * Check course of user has graduation is in-progress
1265 *
1266 * @param $course_id
1267 * @return bool
1268 * @throws Exception
1269 */
1270 public function is_course_in_progress( $course_id ): bool {
1271 $user = learn_press_get_user( $this->get_id() );
1272 $user_course = $user->get_course_data( $course_id );
1273
1274 return $user_course && LP_COURSE_GRADUATION_IN_PROGRESS === $user_course->get_graduation();
1275 }
1276
1277 /**
1278 * Return TRUE if user can do a quiz
1279 *
1280 * @param $quiz_id
1281 * @param int $course_id
1282 *
1283 * @return bool
1284 * @throws Exception
1285 */
1286 public function can_do_quiz( $quiz_id, $course_id = 0 ) {
1287 $course = learn_press_get_course( $course_id );
1288
1289 if ( ! $course->is_no_required_enroll() ) {
1290 $can = $this->has_course_status( $course_id, array( 'enrolled' ) ) && ! $this->has_started_quiz( $quiz_id, $course_id );
1291 } else {
1292 $can = ! $this->has_started_quiz( $quiz_id, $course_id );
1293 }
1294
1295 return apply_filters( 'learn_press_user_can_do_quiz', $can, $quiz_id, $this->get_id(), $course_id );
1296 }
1297
1298 /**
1299 * Check if all items in course completed.
1300 *
1301 * @return boolean
1302 * @author Nhamdv <email@email.com>
1303 */
1304 public function is_completed_all_items( $course_id ) {
1305 $course = learn_press_get_course( $course_id );
1306
1307 $course_data = $this->get_course_data( $course_id );
1308
1309 $course_results = $course_data->get_result();
1310
1311 if ( ! isset( $course_results['completed_items'] ) ) {
1312 return false;
1313 }
1314
1315 return $course_results['completed_items'] >= $course->count_items();
1316 }
1317
1318 public function get_role() {
1319 return $this->is_admin() ? 'admin' : ( $this->is_instructor() ? 'instructor' : 'user' );
1320 }
1321
1322 /**
1323 * Get user course's grade.
1324 * Possible values:
1325 * + passed User has finished and passed course.
1326 * + failed User has finished but failed.
1327 * + in-progress User still is learning course.
1328 *
1329 * @param $course_id
1330 *
1331 * @return string|bool
1332 */
1333 public function get_course_grade( $course_id ) {
1334 $grade = false;
1335 $course_data = $this->get_course_data( $course_id );
1336
1337 if ( $course_data ) {
1338 $grade = $course_data->get_status( 'graduation' );
1339 }
1340
1341 return apply_filters( 'learn-press/user-course-grade', $grade, $this->get_id(), $course_id );
1342 }
1343
1344 /**
1345 * Check if user is a GUEST by checking the meta _lp_temp_user is exists.
1346 *
1347 * @return bool
1348 */
1349 public function is_guest(): bool {
1350 return ! $this->get_id() || ! get_user_by( 'id', $this->get_id() );
1351 }
1352
1353 /**
1354 * Check if user can edit a post.
1355 *
1356 * @param int $post_id
1357 *
1358 * @return bool
1359 */
1360 public function can_edit( int $post_id ): bool {
1361 if ( $this->get_id() !== get_current_user_id() ) {
1362 return false;
1363 }
1364
1365 return current_user_can( 'edit_post', $post_id );
1366 }
1367
1368 /**
1369 * Get email of user
1370 *
1371 * @return string
1372 */
1373 public function get_email(): string {
1374 return $this->get_data( 'email', '' );
1375 }
1376
1377 /**
1378 * Return user_login of the user.
1379 *
1380 * @return string
1381 */
1382 public function get_username(): string {
1383 return $this->get_data( 'user_login', '' );
1384 }
1385
1386 /**
1387 * Return user bio information.
1388 *
1389 * @return string
1390 */
1391 public function get_description(): string {
1392 return $this->get_data( 'description', '' );
1393 }
1394
1395 /**
1396 * Return user first name.
1397 *
1398 * @return string
1399 */
1400 public function get_first_name(): string {
1401 return $this->get_data( 'first_name', '' );
1402 }
1403
1404 /**
1405 * Return user last name.
1406 *
1407 * @return string
1408 */
1409 public function get_last_name(): string {
1410 return $this->get_data( 'last_name', '' );
1411 }
1412
1413 /**
1414 * Return user nickname.
1415 *
1416 * @return string
1417 */
1418 public function get_nickname(): string {
1419 return $this->get_data( 'nickname', '' );
1420 }
1421
1422 /**
1423 * Return user display name.
1424 *
1425 * @return string
1426 */
1427 public function get_display_name(): string {
1428 return $this->get_data( 'display_name', '' );
1429 }
1430 }
1431 }
1432