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/class-lp-user.php +239 -91 4.1.7.34.4.8 View file →
@@ -1,6 +1,10 @@
1 1 <?php
2 2
3 +use LearnPress\Filters\FilterBase;
4 +use LearnPress\Filters\UserItemsFilter;
5 +use LearnPress\Models\UserModel;
6 +
3 7 /**
4 8 * Class LP_User
5 9 *
6 10 * @author ThimPress
@@ -23,9 +27,8 @@
23 27 'learnpress'
24 28 );
25 29
26 30 $course = learn_press_get_course( $course_id );
27 -
28 31 if ( ! $course ) {
29 32 return $view;
30 33 }
31 34
@@ -90,9 +93,9 @@
90 93
91 94 /**
92 95 * Check the user can access to an item inside course.
93 96 *
94 - * @param int $item_id Course's item Id.
97 + * @param int $item_id Course's item Id.
95 98 * @param LP_Model_User_Can_View_Course_Item $view Course Id.
96 99 *
97 100 * @author tungnx
98 101 * @return LP_Model_User_Can_View_Course_Item
@@ -121,9 +124,9 @@
121 124 if ( $view_new ) {
122 125 $view = $view_new;
123 126 }
124 127
125 - return apply_filters( 'learnpress/course/item/can-view', $view, $item );
128 + return apply_filters( 'learnpress/course/item/can-view', $view, $item, $this );
126 129 }
127 130
128 131 /**
129 132 * Check if user can retry course.
@@ -130,9 +133,8 @@
130 133 *
131 134 * @param int $course_id .
132 135 *
133 136 * @return int
134 - * @throws Exception .
135 137 * @since 4.0.0
136 138 * @author tungnx
137 139 */
138 140 public function can_retry_course( int $course_id = 0 ): int {
@@ -195,8 +197,9 @@
195 197 * Check course is enrolled
196 198 *
197 199 * @param integer $course_id Course ID
198 200 * @param boolean $return_bool
201 + *
199 202 * @return bool|object
200 203 * @editor tungnx
201 204 * @since 4.1.2
202 205 * @version 1.0.2
@@ -215,9 +218,8 @@
215 218 throw new Exception( esc_html__( 'Order is not completed', 'learnpress' ) );
216 219 }*/
217 220
218 221 $user_course = $this->get_course_data( $course_id );
219 -
220 222 if ( ! $user_course || ! $user_course->is_enrolled() ) {
221 223 throw new Exception( esc_html__( 'The course is not enrolled.', 'learnpress' ) );
222 224 }
223 225 } catch ( Throwable $th ) {
@@ -235,9 +237,9 @@
235 237 *
236 238 * @return bool
237 239 * @throws Exception
238 240 */
239 - public function has_finished_course( int $course_id ) : bool {
241 + public function has_finished_course( int $course_id ): bool {
240 242 $user_course = $this->get_course_data( $course_id );
241 243
242 244 return apply_filters( 'learn-press/user-has-finished-course', $user_course && $user_course->is_finished(), $this->get_id(), $course_id );
243 245 }
@@ -269,10 +271,11 @@
269 271
270 272 /**
271 273 * Check user can enroll course
272 274 *
273 - * @param int $course_id
275 + * @param int $course_id
274 276 * @param bool $return_bool
277 + *
275 278 * @return mixed|object|bool
276 279 */
277 280 public function can_enroll_course( int $course_id, bool $return_bool = true ) {
278 281 $course = learn_press_get_course( $course_id );
@@ -280,35 +283,53 @@
280 283 $output->check = true;
281 284 $output->message = '';
282 285
283 286 try {
287 + $is_no_required_enroll = $course->get_data( 'no_required_enroll', 'no' ) === 'yes';
284 288 if ( ! $course ) {
289 + $output->code = 'course_unavailable';
285 290 throw new Exception( esc_html__( 'No Course or User available', 'learnpress' ) );
286 291 }
287 292
288 293 if ( ! $course->is_publish() ) {
294 + $output->code = 'course_not_publish';
289 295 throw new Exception( esc_html__( 'The course is not public', 'learnpress' ) );
290 296 }
291 297
292 - if ( $course->get_external_link() && ! $this->has_purchased_course( $course_id ) ) {
293 - throw new Exception( esc_html__( 'The course is external', 'learnpress' ) );
298 + if ( $this->has_enrolled_course( $course_id ) ) {
299 + $output->code = 'course_is_enrolled';
300 + throw new Exception( esc_html__( 'This course is already enrolled.', 'learnpress' ) );
294 301 }
295 302
296 - if ( ! $course->is_in_stock() ) {
303 + if ( ! $course->is_in_stock_enroll() && ! $this->has_purchased_course( $course_id )
304 + && ! $this->has_enrolled_or_finished( $course_id ) && ! $is_no_required_enroll ) {
305 + $output->code = 'course_out_of_stock';
297 306 throw new Exception( esc_html__( 'The course is full of students.', 'learnpress' ) );
298 307 }
299 308
300 - if ( $course->is_no_required_enroll() ) {
301 - throw new Exception( esc_html__( 'The course is not required to enroll.', 'learnpress' ) );
309 + if ( $course->get_external_link()
310 + && ! $this->has_purchased_course( $course_id )
311 + && ! $course->is_offline() ) {
312 + $output->code = 'course_is_external';
313 + throw new Exception( esc_html__( 'The course is external', 'learnpress' ) );
302 314 }
303 315
304 - if ( ! $course->is_free() && ! $this->has_purchased_course( $course_id ) ) {
305 - throw new Exception( esc_html__( 'The course is not purchased.', 'learnpress' ) );
316 + if ( $this->can_retry_course( $course_id ) ) {
317 + $output->code = 'course_can_retry';
318 + throw new Exception( esc_html__( 'Course can retake.', 'learnpress' ) );
306 319 }
307 320
308 - if ( $this->has_enrolled_course( $course_id ) ) {
309 - throw new Exception( esc_html__( 'This course is already enrolled.', 'learnpress' ) );
321 + if ( $is_no_required_enroll && ! is_user_logged_in() ) {
322 + $output->code = 'course_is_no_required_enroll_not_login';
323 + throw new Exception(
324 + esc_html__( 'Enrollment in the course is not mandatory. You can access course for learning now.', 'learnpress' )
325 + );
310 326 }
327 +
328 + if ( ! $course->is_free() && ! $is_no_required_enroll && ! $this->has_purchased_course( $course_id ) ) {
329 + $output->code = 'course_is_not_purchased';
330 + throw new Exception( esc_html__( 'The course is not purchased.', 'learnpress' ) );
331 + }
311 332 } catch ( \Throwable $th ) {
312 333 $output->check = false;
313 334 $output->message = $th->getMessage();
314 335 }
@@ -323,92 +344,75 @@
323 344 /**
324 345 * Check can show purchase course button
325 346 *
326 347 * @param int $course_id
327 - * @return bool
328 - * @throws Exception
348 + *
349 + * @return bool|WP_Error
329 350 * @author nhamdv
330 351 * @editor tungnx
331 - * @modify 4.1.4
332 - * @version 1.0.3
352 + * @since 4.0.8
353 + * @version 1.0.6
333 354 */
334 - public function can_purchase_course( int $course_id = 0 ): bool {
355 + public function can_purchase_course( int $course_id = 0 ) {
335 356 $can_purchase = true;
336 357 $course = learn_press_get_course( $course_id );
358 + $code_err = '';
337 359
338 360 try {
339 - if ( ! $course ) {
340 - throw new Exception( 'Course is unavailable' );
361 + $can_enroll_course = $this->can_enroll_course( $course_id, false );
362 + if ( ! $can_enroll_course->check &&
363 + ! in_array( $can_enroll_course->code, [ 'course_is_not_purchased', 'course_is_enrolled' ] ) ) {
364 + $code_err = $can_enroll_course->code;
365 + throw new Exception( $can_enroll_course->message );
341 366 }
342 367
343 - if ( ! $course->is_publish() ) {
344 - throw new Exception( 'Course is not publish' );
345 - }
346 -
347 368 if ( $course->is_free() ) {
348 - throw new Exception( 'Course is free' );
369 + $code_err = 'course_is_free';
370 + throw new Exception( __( 'Course is free, so you can not purchase', 'learnpress' ) );
349 371 }
350 372
351 - if ( $course->get_external_link() ) {
352 - throw new Exception( 'Course is type external, so can not purchase' );
353 - }
354 -
355 373 // Course is not require enrolling.
356 - if ( $course->is_no_required_enroll() ) {
357 - throw new Exception( 'Course is type no required enroll' );
358 - }
359 -
360 - if ( $this->can_retry_course( $course_id ) ) {
361 - throw new Exception( 'Course is has retake' );
362 - }
363 -
364 - // If course is reached limitation.
365 - if ( ! $course->is_in_stock() ) {
366 - $message = apply_filters(
367 - 'learn-press/maximum-students-reach',
368 - esc_html__( 'This course is out of stock', 'learnpress' )
374 + // Not use $course->is_no_required_enroll() because it is not correct, it check with user logged.
375 + if ( $course->get_data( 'no_required_enroll', 'no' ) === 'yes' ) {
376 + $code_err = 'no_required_enroll';
377 + throw new Exception(
378 + __(
379 + 'Enrollment in the course is not mandatory. You can access materials for learning or to take quizzes now.',
380 + 'learnpress'
381 + )
369 382 );
370 -
371 - if ( $message ) {
372 - learn_press_display_message( $message );
373 - }
374 -
375 - throw new Exception( $message );
376 383 }
377 384
378 385 // If the order contains course is processing
379 386 $order = $this->get_course_order( $course_id );
380 - if ( $order && $order->get_status() === 'processing' ) {
381 - $message = apply_filters(
382 - 'learn-press/order-processing-message',
383 - __( 'Your order is waiting for processing', 'learnpress' )
384 - );
385 -
386 - if ( $message ) {
387 - learn_press_display_message( $message );
388 - }
389 -
390 - throw new Exception( $message );
387 + if ( $order && $order->get_status() === LP_ORDER_PROCESSING ) {
388 + $code_err = 'order_processing';
389 + throw new Exception( __( 'Your order is waiting for processing', 'learnpress' ) );
391 390 }
392 391
393 392 if ( $this->has_purchased_course( $course_id ) ) {
394 - throw new Exception( 'Course is purchased' );
393 + $code_err = 'course_purchased';
394 + throw new Exception( __( 'Course is purchased', 'learnpress' ) );
395 395 }
396 396
397 397 $is_blocked_course = 0 === $course->timestamp_remaining_duration();
398 398 $is_enrolled_course = $this->has_enrolled_course( $course_id );
399 - $is_finished_course = $this->has_finished_course( $course_id );
400 -
401 399 if ( $course->allow_repurchase() ) {
402 400 if ( $is_enrolled_course && ! $is_blocked_course ) {
401 + $code_err = 'course_is_enrolled';
403 402 throw new Exception( 'Course is enrolled' );
404 403 }
405 404 } else {
406 405 if ( $this->has_enrolled_or_finished( $course_id ) ) {
407 - throw new Exception( 'Course is enrolled' );
406 + $code_err = 'course_is_enrolled_or_finished';
407 + throw new Exception( __( 'Course is enrolled or finished', 'learnpress' ) );
408 408 }
409 409 }
410 - } catch ( Exception $e ) {
410 + } catch ( Throwable $e ) {
411 + $can_purchase = new WP_Error( $code_err, $e->getMessage() );
412 + }
413 +
414 + if ( $can_purchase instanceof WP_Error ) {
411 415 $can_purchase = false;
412 416 }
413 417
414 418 return apply_filters( 'learn-press/user/can-purchase-course', $can_purchase, $this->get_id(), $course_id );
@@ -417,8 +421,9 @@
417 421 /**
418 422 * Check condition show finish course button
419 423 *
420 424 * @param $course
425 + *
421 426 * @return array
422 427 * @author nhamdv
423 428 * @editor tungnx
424 429 * @version 1.0.2
@@ -482,23 +487,24 @@
482 487
483 488 /**
484 489 * Start quiz for the user.
485 490 *
486 - * @param int $quiz_id
487 - * @param int $course_id
491 + * @param int $quiz_id
492 + * @param int $course_id
488 493 * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
489 494 *
490 495 * @return LP_User_Item_Quiz|bool|WP_Error
491 496 * @throws Exception
497 + * @deprecated 4.2.9.1
492 498 */
493 499 public function start_quiz( int $quiz_id, int $course_id = 0, bool $wp_error = false ) {
500 + _deprecated_function( __METHOD__, '4.2.9.1' );
501 + return false;
502 +
494 503 try {
495 - $item_id = learn_press_get_request( 'lp-preview' );
496 -
497 - if ( $item_id ) {
498 - learn_press_add_message( __( 'You cannot start a quiz in preview mode.', 'learnpress' ), 'error' );
499 - wp_safe_redirect( learn_press_get_preview_url( $item_id ) );
500 - exit();
504 + $item_is_preview = learn_press_get_request( 'lp-preview' );
505 + if ( $item_is_preview ) {
506 + throw new Exception( __( 'You cannot start a quiz in preview mode.', 'learnpress' ) );
501 507 }
502 508
503 509 // Validate course and quiz
504 510 $course_id = $this->_verify_course_item( $quiz_id, $course_id );
@@ -509,10 +515,8 @@
509 515 );
510 516 }
511 517
512 518 $course = learn_press_get_course( $course_id );
513 - //$access_level = $this->get_course_access_level( $course_id );
514 -
515 519 // If user has already finished the course
516 520 if ( $this->has_finished_course( $course_id ) ) {
517 521 throw new Exception(
518 522 __( 'You have already finished the course of this quiz', 'learnpress' ),
@@ -535,11 +539,11 @@
535 539 __( 'The user has started or completed the quiz.', 'learnpress' ),
536 540 LP_QUIZ_HAS_STARTED_OR_COMPLETED
537 541 );
538 542 }
539 - $user = learn_press_get_current_user();
540 543
541 - if ( $user->is_guest() ) {
544 + $user_current = learn_press_get_current_user();
545 + if ( $user_current->is_guest() ) {
542 546 // if course required enroll => print message "You have to login for starting quiz"
543 547 if ( ! $course->is_no_required_enroll() ) {
544 548 throw new Exception( __( 'You have to log in to start the quiz.', 'learnpress' ), LP_REQUIRE_LOGIN );
545 549 }
@@ -550,9 +554,9 @@
550 554 *
551 555 * @see learn_press_hk_before_start_quiz
552 556 */
553 557 $can_start_quiz = apply_filters(
554 - 'learn-press/before-start-quiz',
558 + 'learn-press/can-start-quiz',
555 559 true,
556 560 $quiz_id,
557 561 $course_id,
558 562 $this->get_id()
@@ -561,9 +565,9 @@
561 565 if ( ! $can_start_quiz ) {
562 566 return false;
563 567 }
564 568
565 - $user_quiz = learn_press_user_start_quiz( $quiz_id, false, $course_id, $wp_error );
569 + $user_quiz = false;
566 570
567 571 /**
568 572 * Hook quiz started
569 573 *
@@ -572,9 +576,9 @@
572 576 do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
573 577
574 578 // $return = $user_quiz->get_mysql_data();
575 579 $return = $user_quiz;
576 - } catch ( Exception $ex ) {
580 + } catch ( Throwable $ex ) {
577 581 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
578 582 }
579 583
580 584 return $return;
@@ -582,10 +586,10 @@
582 586
583 587 /**
584 588 * Finish a quiz for the user and save all data needed
585 589 *
586 - * @param int $quiz_id
587 - * @param int $course_id
590 + * @param int $quiz_id
591 + * @param int $course_id
588 592 * @param bool $wp_error
589 593 *
590 594 * @return LP_User_Item_Quiz|bool|WP_Error
591 595 */
@@ -626,17 +630,18 @@
626 630
627 631 /**
628 632 * Retake a quiz for the user
629 633 *
630 - * @param int $quiz_id
631 - * @param int $course_id
634 + * @param int $quiz_id
635 + * @param int $course_id
632 636 * @param bool $wp_error
633 637 *
634 638 * @return bool|WP_Error|LP_User_Item_Quiz
635 639 *
636 640 * @throws Exception
641 + * @deprecated 4.2.7.2
637 642 */
638 - public function retake_quiz( int $quiz_id, int $course_id, bool $wp_error = false ) {
643 + /*public function retake_quiz( int $quiz_id, int $course_id, bool $wp_error = false ) {
639 644 $return = false;
640 645
641 646 try {
642 647 $course_id = $this->_verify_course_item( $quiz_id, $course_id );
@@ -671,9 +676,9 @@
671 676 // Check if user has already started or completed quiz
672 677 if ( ! $this->has_item_status( array( 'completed' ), $quiz_id, $course_id ) ) {
673 678 throw new Exception(
674 679 sprintf(
675 - __( '%1$s::%2$s - The ser has not completed the quiz.', 'learnpress' ),
680 + __( '%1$s::%2$s - The user has not completed the quiz.', 'learnpress' ),
676 681 __CLASS__,
677 682 __FUNCTION__
678 683 ),
679 684 LP_QUIZ_HAS_STARTED_OR_COMPLETED
@@ -701,18 +706,18 @@
701 706 do_action( 'learn-press/user/retake-quiz-failure', $quiz_id, $course_id, $this->get_id() );
702 707 }
703 708
704 709 return $return;
705 - }
710 + }*/
706 711
707 712 /**
708 713 * Get quiz's user learning or completed
709 714 *
710 - * @param LP_User_Items_Filter $filter
715 + * @param LP_User_Items_Filter|UserItemsFilter $filter
711 716 *
712 717 * @return LP_Query_List_Table
713 718 */
714 - public function get_user_quizzes( LP_User_Items_Filter $filter ): LP_Query_List_Table {
719 + public function get_user_quizzes( $filter ): LP_Query_List_Table {
715 720 $quizzes = [
716 721 'total' => 0,
717 722 'items' => [],
718 723 'pages' => 0,
@@ -788,6 +793,149 @@
788 793 error_log( $e->getMessage() );
789 794 }
790 795
791 796 return $flag;
797 + }
798 +
799 + /**
800 + * Get statistic info of student user
801 + *
802 + * @return array
803 + * @since 4.1.6
804 + * @version 1.0.0
805 + */
806 + public function get_student_statistic(): array {
807 + $user = $this;
808 + $statistic = array(
809 + 'enrolled_courses' => 0,
810 + 'in_progress_course' => 0,
811 + 'finished_courses' => 0,
812 + 'passed_courses' => 0,
813 + 'failed_courses' => 0,
814 + );
815 +
816 + try {
817 + if ( ! $user ) {
818 + throw new Exception( 'The user is invalid' );
819 + }
820 +
821 + $user_id = $user->get_id();
822 + $lp_user_items_db = LP_User_Items_DB::getInstance();
823 +
824 + // Count status
825 + $filter = new LP_User_Items_Filter();
826 + $filter->user_id = $user_id;
827 + $count_status = $lp_user_items_db->count_status_by_items( $filter );
828 + $total_courses_enrolled = intval( $count_status->{LP_COURSE_PURCHASED} ?? 0 )
829 + + intval( $count_status->{LP_COURSE_ENROLLED} ?? 0 )
830 + + intval( $count_status->{LP_COURSE_FINISHED} ?? 0 );
831 +
832 + $statistic['enrolled_courses'] = $total_courses_enrolled;
833 + $statistic['in_progress_course'] = $count_status->{LP_COURSE_GRADUATION_IN_PROGRESS} ?? 0;
834 + $statistic['finished_courses'] = $count_status->{LP_COURSE_FINISHED} ?? 0;
835 + $statistic['passed_courses'] = $count_status->{LP_COURSE_GRADUATION_PASSED} ?? 0;
836 + $statistic['failed_courses'] = $count_status->{LP_COURSE_GRADUATION_FAILED} ?? 0;
837 + } catch ( Throwable $e ) {
838 + error_log( __FUNCTION__ . ': ' . $e->getMessage() );
839 + }
840 +
841 + return apply_filters( 'lp/profile/student/statistic', $statistic, $this );
842 + }
843 +
844 + /**
845 + * Get statistic info of instructor user
846 + *
847 + * @param array $params
848 + *
849 + * @return array
850 + * @since 4.1.6
851 + * @version 1.0.1
852 + */
853 + public function get_instructor_statistic( array $params = [] ): array {
854 + $statistic = array(
855 + 'total_course' => 0,
856 + 'published_course' => 0,
857 + 'pending_course' => 0,
858 + 'total_student' => 0,
859 + 'student_completed' => 0,
860 + 'student_in_progress' => 0,
861 + );
862 +
863 + try {
864 + $user_id = $this->get_id();
865 + $lp_user_items_db = LP_User_Items_DB::getInstance();
866 + $lp_course_db = LP_Course_DB::getInstance();
867 +
868 + if ( ! $this->can_create_course() ) {
869 + throw new Exception( 'The user is not Instructor' );
870 + }
871 +
872 + // Count total user completed course of author
873 + $filter_course = new LP_Course_Filter();
874 + $filter_course->only_fields = array( 'ID' );
875 + $filter_course->post_author = $user_id;
876 + $filter_course->post_status = 'publish';
877 + $filter_course->return_string_query = true;
878 + $query_courses_str = LP_Course_DB::getInstance()->get_courses( $filter_course );
879 +
880 + $filter_count_users = new LP_User_Items_Filter();
881 + $filter_count_users->item_type = LP_COURSE_CPT;
882 + $filter_count_users->where[] = "AND item_id IN ({$query_courses_str})";
883 + $count_student_has_status = $lp_user_items_db->count_status_by_items( $filter_count_users );
884 + // Count total user in progress course of author
885 +
886 + // Get total users attend course of author
887 + $filter_count_users = $lp_user_items_db->count_user_attend_courses_of_author( $user_id );
888 + $count_users_attend_courses_of_author = $lp_user_items_db->get_user_courses( $filter_count_users );
889 +
890 + // Get total courses publish of author
891 + $filter_count_courses = $lp_course_db->count_courses_of_author( $user_id, [ 'publish' ] );
892 + $total_courses_publish_of_author = $lp_course_db->get_courses( $filter_count_courses );
893 +
894 + // Get total courses of author
895 + $filter_count_courses = $lp_course_db->count_courses_of_author( $user_id );
896 + $total_courses_of_author = $lp_course_db->get_courses( $filter_count_courses );
897 +
898 + // Get total courses pending of author
899 + $filter_count_courses = $lp_course_db->count_courses_of_author( $user_id, [ 'pending' ] );
900 + $total_courses_pending_of_author = $lp_course_db->get_courses( $filter_count_courses );
901 +
902 + $statistic['total_course'] = $total_courses_of_author;
903 + $statistic['published_course'] = $total_courses_publish_of_author;
904 + $statistic['pending_course'] = $total_courses_pending_of_author;
905 + $statistic['total_student'] = $count_users_attend_courses_of_author;
906 + $statistic['student_completed'] = $count_student_has_status->{LP_COURSE_FINISHED} ?? 0;
907 + $statistic['student_in_progress'] = $count_student_has_status->{LP_COURSE_GRADUATION_IN_PROGRESS} ?? 0;
908 + } catch ( Throwable $e ) {
909 + error_log( __FUNCTION__ . ': ' . $e->getMessage() );
910 + }
911 +
912 + return apply_filters( 'lp/profile/instructor/statistic', $statistic, $this );
913 + }
914 +
915 + /**
916 + * Get url instructor.
917 + *
918 + * @return string
919 + * @version 1.0.1
920 + * @since 4.2.3
921 + */
922 + public function get_url_instructor(): string {
923 + $single_instructor_link = '';
924 +
925 + try {
926 + $author_id = $this->get_id();
927 + $userModel = UserModel::find( $author_id, true );
928 + if ( ! $userModel ) {
929 + throw new Exception( 'User not found' );
930 + }
931 +
932 + $single_instructor_page_id = learn_press_get_page_id( 'single_instructor' );
933 + $user_slug = $userModel->get_slug_link();
934 + $single_instructor_link = trailingslashit( trailingslashit( get_page_link( $single_instructor_page_id ) ) . $user_slug );
935 + } catch ( Throwable $e ) {
936 + LP_Debug::error_log( $e );
937 + }
938 +
939 + return $single_instructor_link;
792 940 }
793 941 }