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

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

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