PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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
← All changes | inc/user/abstract-lp-user.php +1333 -1333 4.3.94.4.8 View file →
@@ -1,1333 +1,1333 @@
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 -}
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 +}