PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9 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 All 140 releases
← All changes | inc/user/abstract-lp-user.php +1345 -1333 4.3.9.1 → 4.4.9 View file →
@@ -1,1333 +1,1345 @@
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 protected]>
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 + /**
650 + * LP_User_Item::complete() writes straight to the table, so it never runs
651 + * UserCourseModel::clean_caches() the way UserItemModel::save() does. The
652 + * cached model still reports the enrollment as in progress, and that cache
653 + * outlives the request wherever a persistent object cache is installed - the
654 + * course then reads back unfinished and keeps offering "Finish course".
655 + */
656 + $userCourseModel = UserCourseModel::find( $this->get_id(), $course_id );
657 + if ( $userCourseModel instanceof UserCourseModel ) {
658 + $userCourseModel->clean_caches();
659 + }
660 +
661 + do_action( 'learn-press/user-course-finished', $course_id, $this->get_id(), $return );
662 + }
663 + }
664 +
665 + return apply_filters( 'learn-press/user-course-finished-data', $return, $course_id, $this->get_id() );
666 + }
667 +
668 + /**
669 + * Check user instructor.
670 + *
671 + * @return bool
672 + */
673 + public function is_instructor(): bool {
674 +
675 + $roles = $this->get_data( 'roles' ) ? $this->get_data( 'roles' ) : array();
676 +
677 + return in_array( LP_TEACHER_ROLE, $roles );
678 + }
679 +
680 + /**
681 + * Check user admin.
682 + *
683 + * @return bool
684 + */
685 + public function is_admin() {
686 + $roles = $this->get_data( 'roles' ) ? $this->get_data( 'roles' ) : array();
687 +
688 + return in_array( 'administrator', $roles );
689 + }
690 +
691 +
692 + public function can_create_course() {
693 + return $this->is_instructor() || $this->is_admin();
694 + }
695 +
696 + /**
697 + * Wrap function to check this user is author of a post.
698 + *
699 + * @param int $post_id
700 + *
701 + * @return bool
702 + * @since 3.1.0
703 + */
704 + public function is_author_of( $post_id ) {
705 + return absint( get_post_field( 'post_author', $post_id ) ) === $this->get_id();
706 + }
707 +
708 + public function get( $role ) {
709 + $args = func_get_args();
710 + unset( $args[0] );
711 + $method = 'get_' . preg_replace( '!-!', '_', $role );
712 + $callback = array( $this, $method );
713 + if ( is_callable( $callback ) ) {
714 + return call_user_func_array( $callback, $args );
715 + } else {
716 + throw new Exception( sprintf( __( 'The role %s for the user doesn\'t exist', 'learnpress' ), $role ) );
717 + }
718 + }
719 +
720 + /**
721 + * Check user has passed course.
722 + *
723 + * @param $course_id
724 + *
725 + * @return mixed
726 + */
727 + public function has_passed_course( $course_id ) {
728 + $user_course = $this->get_course_data( $course_id );
729 +
730 + return $user_course && $user_course->is_passed();
731 + }
732 +
733 + /**
734 + * Checks if user has started a quiz
735 + * - FALSE if user has not started quiz
736 + * - String if user has started quiz (status of quiz)
737 + *
738 + * @param int $quiz_id
739 + * @param int $course_id
740 + *
741 + * @return mixed
742 + */
743 + public function has_started_quiz( $quiz_id, $course_id = 0 ) {
744 + $course_id = $this->_get_course( $course_id );
745 + $started = false;
746 + $started = $this->has_quiz_status( array( 'started', 'completed' ), $quiz_id, $course_id );
747 +
748 + return apply_filters( 'learn_press_user_started_quiz', $started, $quiz_id, $course_id, $this->get_id() );
749 + }
750 +
751 + /**
752 + * Return true if user has completed a quiz
753 + *
754 + * @param int $quiz_id
755 + * @param int $course_id
756 + *
757 + * @return bool
758 + * @deprecated 4.1.6.9
759 + */
760 + /*public function has_completed_quiz( $quiz_id, $course_id = 0 ): bool {
761 + return $this->get_item_status( $quiz_id, $course_id ) == 'completed';
762 + }*/
763 +
764 + /**
765 + * Mark a lesson is completed for user
766 + *
767 + * @param int $lesson_id
768 + * @param int $course_id
769 + *
770 + * @return bool|WP_Error
771 + */
772 + public function complete_lesson( $lesson_id = 0, $course_id = 0 ) {
773 + $result = true;
774 +
775 + try {
776 + $course = learn_press_get_course( $course_id );
777 + if ( ! $course ) {
778 + throw new Exception( __( 'Invalid course', 'learnpress' ) );
779 + }
780 +
781 + $course_data = $this->get_course_data( $course_id );
782 + if ( ! $course_data ) {
783 + throw new Exception( __( 'You must enroll course!', 'learnpress' ) );
784 + }
785 +
786 + /**
787 + * If user has stared a lesson, get user lesson information
788 + */
789 + $item = $course_data->get_item( $lesson_id );
790 + if ( ! $item ) {
791 + throw new Exception( __( 'Invalid lesson', 'learnpress' ) );
792 + }
793 +
794 + if ( $item->is_completed() ) {
795 + throw new Exception( __( 'You have already completed this lesson.', 'learnpress' ) );
796 + }
797 +
798 + $item->set_graduation( 'passed' );
799 + $updated = $item->complete();
800 +
801 + do_action( 'learn-press/user-completed-lesson', $lesson_id, $course_id, $this->get_id() );
802 + } catch ( Throwable $e ) {
803 + $result = new WP_Error( 'error_lesson_complete', $e->getMessage() );
804 + }
805 +
806 + return $result;
807 + }
808 +
809 + /**
810 + * Returns TRUE if user has already completed a lesson
811 + *
812 + * @param int $lesson_id Lesson id.
813 + * @param null $course_id Course id.
814 + *
815 + * @return bool
816 + * @deprecated 4.1.6.9
817 + */
818 + public function has_completed_lesson( $lesson_id = 0, $course_id = null ): bool {
819 + return 'completed' === $this->get_item_status( $lesson_id, $course_id );
820 + }
821 +
822 + /**
823 + * Return current status of course for user
824 + *
825 + * @param int $course_id
826 + * @param string $field
827 + * @param bool $force
828 + *
829 + * @return mixed
830 + */
831 + public function get_course_info( int $course_id, $field = null, $force = false ) {
832 + $user_data = $this->get_course_data( $course_id );
833 + if ( $user_data ) {
834 + return $user_data->get_results( $field );
835 + }
836 +
837 + return false;
838 + }
839 +
840 + /**
841 + * @param $course_id
842 + *
843 + * @return int
844 + * @deprecated 4.1.6.9
845 + */
846 + public function get_course_history_id( $course_id ) {
847 + $history = $this->get_course_info( $course_id );
848 +
849 + return ! empty( $history['history_id'] ) ? $history['history_id'] : 0;
850 + }
851 +
852 + /**
853 + * Get current status of a course for user.
854 + *
855 + * @param int $course_id
856 + *
857 + * @return mixed
858 + * @editor tungnx
859 + * @modify 4.1.3
860 + * @version 1.0.1
861 + */
862 + public function get_course_status( int $course_id ): string {
863 + $status = '';
864 +
865 + try {
866 + $user_data = $this->get_course_data( $course_id );
867 +
868 + if ( $user_data ) {
869 + $status = $user_data->get_status();
870 + }
871 + } catch ( Throwable $e ) {
872 + if ( LP_Debug::is_debug() ) {
873 + error_log( $e->getMessage() );
874 + }
875 + }
876 +
877 + return apply_filters( 'learn-press/user-course-status', $status, $course_id, $this->get_id() );
878 + }
879 +
880 + /**
881 + * Get order status of a course.
882 + *
883 + * @param int $course_id
884 + *
885 + * @return mixed
886 + */
887 + public function get_order_status( $course_id ) {
888 + try {
889 + $order = $this->get_course_order( $course_id );
890 +
891 + if ( ! $order ) {
892 + throw new Exception( 'Order not exists' );
893 + }
894 +
895 + $order_status = apply_filters(
896 + 'learn-press/course-order-status',
897 + get_post_status( $order->get_id() ),
898 + $course_id,
899 + $this->get_id()
900 + );
901 + } catch ( Throwable $e ) {
902 + $order_status = false;
903 + }
904 +
905 + return $order_status;
906 + }
907 +
908 + /**
909 + * Check item completed.
910 + *
911 + * @param $item
912 + * @param int $course_id
913 + * @param bool $force
914 + *
915 + * @return mixed|void
916 + * @version 3.0.1
917 + * @since 3.0.0
918 + */
919 + public function has_completed_item( $item, $course_id = 0, $force = false ) {
920 + $course_id = $this->_get_course( $course_id );
921 +
922 + $return = false;
923 + $item_id = 0;
924 + if ( is_numeric( $item ) ) {
925 + $item_id = absint( $item );
926 + } else {
927 + settype( $item, 'array' );
928 + if ( ! empty( $item['ID'] ) ) {
929 + $item_id = absint( $item['ID'] );
930 + }
931 + }
932 +
933 + if ( $item_id ) {
934 + $return = 'completed' === $this->get_item_status( $item_id, $course_id );
935 + }
936 +
937 + return apply_filters( 'learn_press_user_has_completed_item', $return, $item );
938 + }
939 +
940 + /**
941 + * Get the order that contains the course.
942 + *
943 + * @param int $course_id
944 + *
945 + * @return bool|LP_Order
946 + * @editor tungnx
947 + * @throws Exception
948 + * @version 1.0.2
949 + * @since 4.1.1
950 + */
951 + public function get_course_order( int $course_id ) {
952 + $lp_order = false;
953 + $lp_order_db = LP_Order_DB::getInstance();
954 + $lp_order_id = $lp_order_db->get_last_lp_order_id_of_user_course( $this->get_id(), $course_id );
955 +
956 + if ( $lp_order_id ) {
957 + $lp_order = new LP_Order( $lp_order_id );
958 + }
959 +
960 + return $lp_order;
961 + }
962 +
963 + /**
964 + * @param $question_id
965 + *
966 + * @return null|string
967 + */
968 + public function get_quiz_by_question( $question_id ) {
969 + global $wpdb;
970 + $query = $wpdb->prepare(
971 + "
972 + SELECT quiz_id
973 + FROM {$wpdb->prefix}learnpress_user_items uq
974 + 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
975 + ",
976 + 'questions',
977 + '%i:' . $wpdb->esc_like( $question_id . '' ) . ';%'
978 + );
979 +
980 + return $wpdb->get_var( $query );
981 + }
982 +
983 + /**
984 + * @return array
985 + */
986 + public function get_roles() {
987 + return (array) $this->get_data( 'roles' );
988 + }
989 +
990 + /**
991 + * @param $question_id
992 + * @param $quiz_id
993 + * @param int $course_id
994 + *
995 + * @return bool
996 + */
997 + public function has_checked_answer( $question_id, $quiz_id, $course_id = 0 ) {
998 + if ( ! $course_id ) {
999 + $course_id = get_the_ID();
1000 + }
1001 +
1002 + $quiz_data = $this->get_item_data( $quiz_id, $course_id );
1003 +
1004 + return $quiz_data ? $quiz_data->has_checked_question( $question_id ) : false;
1005 + }
1006 +
1007 + /**
1008 + * Return TRUE if user is already exists.
1009 + *
1010 + * @return bool
1011 + */
1012 + public function is_exists() {
1013 + return ! ! get_user_by( 'id', $this->get_id() );
1014 + }
1015 +
1016 + /**
1017 + * Check if the user is logged in.
1018 + *
1019 + * @return bool
1020 + */
1021 + public function is_logged_in() {
1022 + return $this->get_id() == get_current_user_id();
1023 + }
1024 +
1025 + /**
1026 + * Get upload profile src
1027 + * Option: null: get origin picture, "thumbnail": get thumbnail picture
1028 + *
1029 + * @param mixed $size
1030 + *
1031 + * @return string
1032 + */
1033 + public function get_upload_profile_src() {
1034 + return LP_Profile::instance( $this->get_id() )->get_upload_profile_src();
1035 + }
1036 +
1037 + /**
1038 + * Get profile avatar url
1039 + *
1040 + * @return string
1041 + * @since 4.2.7.2
1042 + * @version 1.0.0
1043 + */
1044 + public function get_profile_avatar_url(): string {
1045 + $avatar_url = $this->get_upload_profile_src();
1046 + if ( empty( $avatar_url ) ) {
1047 + $args = learn_press_get_avatar_thumb_size();
1048 + $avatar_url = get_avatar_url( $this->get_id(), $args );
1049 + if ( empty( $avatar_url ) ) {
1050 + $avatar_url = LP_PLUGIN_URL . 'assets/images/avatar-default.png';
1051 + }
1052 + }
1053 +
1054 + return $avatar_url;
1055 + }
1056 +
1057 + /**
1058 + * @param string $type
1059 + * @param int $size
1060 + * @param bool $src_only
1061 + *
1062 + * @return false|string
1063 + */
1064 + public function get_profile_picture( $type = '', $size = 96, $src_only = false ) {
1065 + return LP_Profile::instance( $this->get_id() )->get_profile_picture( $type, $size );
1066 + }
1067 +
1068 + /**
1069 + * Get links socials of use on Profile page
1070 + * Icon is font awesome
1071 + *
1072 + * @param int $user_id
1073 + * @return array
1074 + * @deprecated 4.2.3
1075 + */
1076 + public function get_profile_socials( int $user_id = 0 ): array {
1077 + $socials = array();
1078 + $extra_info = learn_press_get_user_extra_profile_info( $user_id );
1079 +
1080 + if ( $extra_info ) {
1081 + foreach ( $extra_info as $k => $v ) {
1082 + if ( empty( $v ) ) {
1083 + continue;
1084 + }
1085 +
1086 + switch ( $k ) {
1087 + case 'facebook':
1088 + $i = '<i class="lp-icon-facebook-f"></i>';
1089 + break;
1090 + case 'twitter':
1091 + $i = '<i class="lp-icon-twitter"></i>';
1092 + break;
1093 + case 'googleplus':
1094 + $i = '<i class="lp-icon-google-plus"></i>';
1095 + break;
1096 + case 'youtube':
1097 + $i = '<i class="lp-icon-youtube-play"></i>';
1098 + break;
1099 + case 'linkedin':
1100 + $i = '<i class="lp-icon-linkedin"></i>';
1101 + break;
1102 + default:
1103 + $i = sprintf( '<i class="lp-icon-%s"></i>', $k );
1104 + }
1105 +
1106 + $icon = apply_filters(
1107 + 'learn-press/user-profile-social-icon',
1108 + $i,
1109 + $k,
1110 + $this->get_id(),
1111 + $this
1112 + );
1113 + $socials[ $k ] = sprintf( '<a href="%s">%s</a>', esc_url_raw( $v ), $icon );
1114 + }
1115 + }
1116 +
1117 + return apply_filters( 'learn-press/user-profile-socials', $socials, $this->get_id(), $this );
1118 + }
1119 +
1120 + /**
1121 + * Get links socials of use on Profile page
1122 + * Icon is svg
1123 + *
1124 + * @param int $user_id
1125 + * @return array
1126 + * @since 4.2.3
1127 + * @version 1.0.0
1128 + */
1129 + public function get_profile_social( int $user_id = 0 ): array {
1130 + $socials = array();
1131 + $extra_info = learn_press_get_user_extra_profile_info( $user_id );
1132 +
1133 + if ( $extra_info ) {
1134 + foreach ( $extra_info as $k => $v ) {
1135 + if ( empty( $v ) ) {
1136 + continue;
1137 + }
1138 +
1139 + switch ( $k ) {
1140 + case 'facebook':
1141 + $i = '<i class="lp-user-ico lp-icon-facebook"></i>';
1142 + break;
1143 + case 'twitter':
1144 + $i = '<i class="lp-user-ico lp-icon-twitter"></i>';
1145 + break;
1146 + case 'linkedin':
1147 + $i = '<i class="lp-user-ico lp-icon-linkedin"></i>';
1148 + break;
1149 + case 'youtube':
1150 + $i = '<i class="lp-user-ico lp-icon-youtube-play"></i>';
1151 + break;
1152 + default:
1153 + $i = sprintf( '<i class="lp-user-ico lp-icon-%s"></i>', esc_attr( $k ) );
1154 + }
1155 +
1156 + $icon = apply_filters(
1157 + 'learn-press/user-profile-social-icon',
1158 + $i,
1159 + $k,
1160 + $this->get_id(),
1161 + $this
1162 + );
1163 + $socials[ $k ] = sprintf( '<a href="%s">%s</a>', esc_url_raw( $v ), $icon );
1164 + }
1165 + }
1166 +
1167 + return apply_filters( 'learn-press/user-profile-socials', $socials, $this->get_id(), $this );
1168 + }
1169 +
1170 + /**
1171 + * Check course of user has graduation is in-progress
1172 + *
1173 + * @param $course_id
1174 + * @return bool
1175 + * @throws Exception
1176 + */
1177 + public function is_course_in_progress( $course_id ): bool {
1178 + $user = learn_press_get_user( $this->get_id() );
1179 + $user_course = $user->get_course_data( $course_id );
1180 +
1181 + return $user_course && LP_COURSE_GRADUATION_IN_PROGRESS === $user_course->get_graduation();
1182 + }
1183 +
1184 + /**
1185 + * Return TRUE if user can do a quiz
1186 + *
1187 + * @param $quiz_id
1188 + * @param int $course_id
1189 + *
1190 + * @return bool
1191 + * @throws Exception
1192 + */
1193 + public function can_do_quiz( $quiz_id, $course_id = 0 ) {
1194 + $course = learn_press_get_course( $course_id );
1195 +
1196 + if ( ! $course->is_no_required_enroll() ) {
1197 + $can = $this->has_course_status( $course_id, array( 'enrolled' ) ) && ! $this->has_started_quiz( $quiz_id, $course_id );
1198 + } else {
1199 + $can = ! $this->has_started_quiz( $quiz_id, $course_id );
1200 + }
1201 +
1202 + return apply_filters( 'learn_press_user_can_do_quiz', $can, $quiz_id, $this->get_id(), $course_id );
1203 + }
1204 +
1205 + /**
1206 + * Check if all items in course completed.
1207 + *
1208 + * @return boolean
1209 + * @author Nhamdv <[email protected]>
1210 + */
1211 + public function is_completed_all_items( $course_id ) {
1212 + $course = learn_press_get_course( $course_id );
1213 +
1214 + $course_data = $this->get_course_data( $course_id );
1215 +
1216 + $course_results = $course_data->get_result();
1217 +
1218 + if ( ! isset( $course_results['completed_items'] ) ) {
1219 + return false;
1220 + }
1221 +
1222 + return $course_results['completed_items'] >= $course->count_items();
1223 + }
1224 +
1225 + /**
1226 + * Get role of user.
1227 + *
1228 + * @return string
1229 + * @since 3.0.0
1230 + * @version 1.0.1
1231 + */
1232 + public function get_role() {
1233 + return $this->get_data( 'role' );
1234 + }
1235 +
1236 + /**
1237 + * Get user course's grade.
1238 + * Possible values:
1239 + * + passed User has finished and passed course.
1240 + * + failed User has finished but failed.
1241 + * + in-progress User still is learning course.
1242 + *
1243 + * @param $course_id
1244 + *
1245 + * @return string|bool
1246 + */
1247 + public function get_course_grade( $course_id ) {
1248 + $grade = false;
1249 + $course_data = $this->get_course_data( $course_id );
1250 +
1251 + if ( $course_data ) {
1252 + $grade = $course_data->get_status( 'graduation' );
1253 + }
1254 +
1255 + return apply_filters( 'learn-press/user-course-grade', $grade, $this->get_id(), $course_id );
1256 + }
1257 +
1258 + /**
1259 + * Check if user is a GUEST by checking the meta _lp_temp_user is exists.
1260 + *
1261 + * @return bool
1262 + */
1263 + public function is_guest(): bool {
1264 + return $this instanceof LP_User_Guest;
1265 + }
1266 +
1267 + /**
1268 + * Check if user can edit a post.
1269 + *
1270 + * @param int $post_id
1271 + *
1272 + * @return bool
1273 + */
1274 + public function can_edit( int $post_id ): bool {
1275 + if ( $this->get_id() !== get_current_user_id() ) {
1276 + return false;
1277 + }
1278 +
1279 + return current_user_can( 'edit_post', $post_id );
1280 + }
1281 +
1282 + /**
1283 + * Get email of user
1284 + *
1285 + * @return string
1286 + */
1287 + public function get_email(): string {
1288 + return $this->get_data( 'email', '' );
1289 + }
1290 +
1291 + /**
1292 + * Return user_login of the user.
1293 + *
1294 + * @return string
1295 + */
1296 + public function get_username(): string {
1297 + return $this->get_data( 'user_login', '' );
1298 + }
1299 +
1300 + /**
1301 + * Return user bio information.
1302 + *
1303 + * @return string
1304 + */
1305 + public function get_description(): string {
1306 + return get_the_author_meta( 'description', $this->get_id() );
1307 + }
1308 +
1309 + /**
1310 + * Return user first name.
1311 + *
1312 + * @return string
1313 + */
1314 + public function get_first_name(): string {
1315 + return $this->get_data( 'first_name', '' );
1316 + }
1317 +
1318 + /**
1319 + * Return user last name.
1320 + *
1321 + * @return string
1322 + */
1323 + public function get_last_name(): string {
1324 + return $this->get_data( 'last_name', '' );
1325 + }
1326 +
1327 + /**
1328 + * Return user nickname.
1329 + *
1330 + * @return string
1331 + */
1332 + public function get_nickname(): string {
1333 + return $this->get_data( 'nickname', '' );
1334 + }
1335 +
1336 + /**
1337 + * Return user display name.
1338 + *
1339 + * @return string
1340 + */
1341 + public function get_display_name(): string {
1342 + return $this->get_data( 'display_name', '' );
1343 + }
1344 + }
1345 +}