PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.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 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.3.8, at inc/user/abstract-lp-user.php

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