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

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

793 lines 21.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_User
5 *
6 * @author ThimPress
7 * @package LearnPress/Classes
8 * @version 1.0.1
9 */
10 class LP_User extends LP_Abstract_User {
11 /**
12 * Check the user can view content items' course
13 *
14 * @param int $course_id
15 *
16 * @return LP_Model_User_Can_View_Course_Item
17 * @throws Exception
18 */
19 public function can_view_content_course( int $course_id = 0 ): LP_Model_User_Can_View_Course_Item {
20 $view = new LP_Model_User_Can_View_Course_Item();
21 $view->message = esc_html__(
22 'This content is protected. Please enroll in the course to view this content!',
23 'learnpress'
24 );
25
26 $course = learn_press_get_course( $course_id );
27
28 if ( ! $course ) {
29 return $view;
30 }
31
32 if ( $this->is_admin() || $this->is_author_of( $course_id ) ) {
33 $view->flag = true;
34 $view->message = 'User can view because is Admin or author of course';
35
36 return $view;
37 }
38
39 // Set view->flag is true if course is no required enroll
40 if ( $course->is_no_required_enroll() ) {
41 $view->flag = true;
42
43 return $view;
44 } elseif ( ! is_user_logged_in() ) {
45 $view->message = __(
46 'This content is protected. Please log in or enroll in the course to view this content!',
47 'learnpress'
48 );
49
50 return $view;
51 }
52
53 if ( $course->is_publish() ) {
54 $is_enrolled_or_finished = $this->has_enrolled_or_finished( $course_id );
55
56 if ( $is_enrolled_or_finished ) {
57 $is_finished_course = $this->has_finished_course( $course_id );
58 $enable_block_item_when_finish = $course->enable_block_item_when_finish();
59
60 if ( $is_finished_course && $enable_block_item_when_finish ) {
61 $view->key = LP_BLOCK_COURSE_FINISHED;
62 $view->message = __(
63 'You finished this course. This content is protected. Please enroll in the course to view this content!',
64 'learnpress'
65 );
66 } elseif ( 0 === $course->timestamp_remaining_duration() ) {
67 $view->key = LP_BLOCK_COURSE_DURATION_EXPIRE;
68 $view->message = __(
69 'The content of this item has been blocked because the course has exceeded its duration.',
70 'learnpress'
71 );
72 } elseif ( $this->get_course_status( $course_id ) === LP_COURSE_PURCHASED ) {
73 $view->key = LP_BLOCK_COURSE_PURCHASE;
74 $view->message = __(
75 'This content is protected. Please enroll in the course to view this content!',
76 'learnpress'
77 );
78 } else {
79 $view->key = 'can_view_course';
80 $view->flag = true;
81 $view->message = '';
82 }
83 }
84 }
85
86 // Todo: set cache - tungnx
87
88 return apply_filters( 'learnpress/course/can-view-content', $view, $this->get_id(), $course );
89 }
90
91 /**
92 * Check the user can access to an item inside course.
93 *
94 * @param int $item_id Course's item Id.
95 * @param LP_Model_User_Can_View_Course_Item $view Course Id.
96 *
97 * @author tungnx
98 * @return LP_Model_User_Can_View_Course_Item
99 * @since 4.0.0
100 */
101 public function can_view_item( int $item_id = 0, $view = null ): LP_Model_User_Can_View_Course_Item {
102 $view_new = null;
103
104 if ( ! $view instanceof LP_Model_User_Can_View_Course_Item ) {
105 return new LP_Model_User_Can_View_Course_Item();
106 }
107
108 $item = LP_Course_Item::get_item( $item_id );
109
110 if ( ! $item ) {
111 return $view;
112 }
113
114 if ( $item instanceof LP_Course_Item && $item->is_preview() ) {
115 $view_new = clone $view; // or create new LP_Model_User_Can_View_Course_Item()
116 $view_new->flag = true;
117 $view_new->key = 'lesson_preview';
118 $view_new->message = '';
119 }
120
121 if ( $view_new ) {
122 $view = $view_new;
123 }
124
125 return apply_filters( 'learnpress/course/item/can-view', $view, $item );
126 }
127
128 /**
129 * Check if user can retry course.
130 *
131 * @param int $course_id .
132 *
133 * @return int
134 * @throws Exception .
135 * @since 4.0.0
136 * @author tungnx
137 */
138 public function can_retry_course( int $course_id = 0 ): int {
139 $flag = 0;
140
141 try {
142 $course = learn_press_get_course( $course_id );
143
144 if ( ! $course ) {
145 throw new Exception( 'Course is not available' );
146 }
147
148 $retake_option = (int) $course->get_data( 'retake_count' );
149
150 if ( $retake_option > 0 ) {
151 /**
152 * Check course is finished
153 * Check duration is blocked
154 */
155 if ( ! $this->has_finished_course( $course->get_id() ) ) {
156 if ( 0 !== $course->timestamp_remaining_duration() ) {
157 throw new Exception();
158 }
159 }
160
161 $user_course_data = $this->get_course_data( $course_id );
162 if ( $user_course_data instanceof LP_User_Item_Course ) {
163 $retaken = $user_course_data->get_retaken_count();
164 $can_retake_times = $retake_option - $retaken;
165
166 if ( $can_retake_times > 0 ) {
167 $flag = $can_retake_times;
168 }
169 }
170 }
171 } catch ( Exception $e ) {
172
173 }
174
175 return apply_filters( 'learn-press/user/course/can-retry', $flag, $this->get_id(), $course_id );
176 }
177
178 /**
179 * Return true if user has already purchased course
180 *
181 * @param int $course_id
182 *
183 * @return bool
184 * @editor tungnx
185 * @modify 4.1.3
186 * @throws Exception
187 */
188 public function has_purchased_course( int $course_id ): bool {
189 $user_course = $this->get_course_data( $course_id );
190
191 return apply_filters( 'learn-press/user-purchased-course', $user_course && $user_course->is_purchased(), $course_id, $this->get_id() );
192 }
193
194 /**
195 * Check course is enrolled
196 *
197 * @param integer $course_id Course ID
198 * @param boolean $return_bool
199 * @return bool|object
200 * @editor tungnx
201 * @since 4.1.2
202 * @version 1.0.2
203 *
204 * @author Nhamdv
205 */
206 public function has_enrolled_course( int $course_id, bool $return_bool = true ) {
207 $result_check = new stdClass();
208 $result_check->check = true;
209 $result_check->message = '';
210
211 try {
212 /*$order = $this->get_course_order( $course_id );
213
214 if ( ! $order || ! $order->is_completed() ) {
215 throw new Exception( esc_html__( 'Order is not completed', 'learnpress' ) );
216 }*/
217
218 $user_course = $this->get_course_data( $course_id );
219
220 if ( ! $user_course || ! $user_course->is_enrolled() ) {
221 throw new Exception( esc_html__( 'The course is not enrolled.', 'learnpress' ) );
222 }
223 } catch ( Throwable $th ) {
224 $result_check->check = false;
225 $result_check->message = $th->getMessage();
226 }
227
228 return apply_filters( 'learn-press/user/is-course-enrolled', $return_bool ? $result_check->check : $result_check, $course_id, $return_bool );
229 }
230
231 /**
232 * Return true if user has finished a course
233 *
234 * @param int $course_id .
235 *
236 * @return bool
237 * @throws Exception
238 */
239 public function has_finished_course( int $course_id ) : bool {
240 $user_course = $this->get_course_data( $course_id );
241
242 return apply_filters( 'learn-press/user-has-finished-course', $user_course && $user_course->is_finished(), $this->get_id(), $course_id );
243 }
244
245 /**
246 * Check course of user is enrolled or finished
247 *
248 * @param int $course_id
249 *
250 * @return bool
251 */
252 public function has_enrolled_or_finished( int $course_id ): bool {
253 $status = true;
254
255 try {
256 $user_course = $this->get_course_data( $course_id );
257
258 if ( ! $user_course ) {
259 $status = false;
260 } elseif ( ! $user_course->is_enrolled() && ! $user_course->is_finished() ) {
261 $status = false;
262 }
263 } catch ( Throwable $e ) {
264 $status = false;
265 }
266
267 return apply_filters( 'learn-press/user-has-finished-course', $status, $this->get_id(), $course_id );
268 }
269
270 /**
271 * Check user can enroll course
272 *
273 * @param int $course_id
274 * @param bool $return_bool
275 * @return mixed|object|bool
276 */
277 public function can_enroll_course( int $course_id, bool $return_bool = true ) {
278 $course = learn_press_get_course( $course_id );
279 $output = new stdClass();
280 $output->check = true;
281 $output->message = '';
282
283 try {
284 if ( ! $course ) {
285 throw new Exception( esc_html__( 'No Course or User available', 'learnpress' ) );
286 }
287
288 if ( ! $course->is_publish() ) {
289 throw new Exception( esc_html__( 'The course is not public', 'learnpress' ) );
290 }
291
292 if ( $course->get_external_link() && ! $this->has_purchased_course( $course_id ) ) {
293 throw new Exception( esc_html__( 'The course is external', 'learnpress' ) );
294 }
295
296 if ( ! $course->is_in_stock() ) {
297 throw new Exception( esc_html__( 'The course is full of students.', 'learnpress' ) );
298 }
299
300 if ( $course->is_no_required_enroll() ) {
301 throw new Exception( esc_html__( 'The course is not required to enroll.', 'learnpress' ) );
302 }
303
304 if ( ! $course->is_free() && ! $this->has_purchased_course( $course_id ) ) {
305 throw new Exception( esc_html__( 'The course is not purchased.', 'learnpress' ) );
306 }
307
308 if ( $this->has_enrolled_course( $course_id ) ) {
309 throw new Exception( esc_html__( 'This course is already enrolled.', 'learnpress' ) );
310 }
311 } catch ( \Throwable $th ) {
312 $output->check = false;
313 $output->message = $th->getMessage();
314 }
315
316 if ( $return_bool ) {
317 $output = $output->check;
318 }
319
320 return apply_filters( 'learn-press/user/can-enroll-course', $output, $course, $return_bool, $this );
321 }
322
323 /**
324 * Check can show purchase course button
325 *
326 * @param int $course_id
327 * @return bool
328 * @throws Exception
329 * @author nhamdv
330 * @editor tungnx
331 * @modify 4.1.4
332 * @version 1.0.3
333 */
334 public function can_purchase_course( int $course_id = 0 ): bool {
335 $can_purchase = true;
336 $course = learn_press_get_course( $course_id );
337
338 try {
339 if ( ! $course ) {
340 throw new Exception( 'Course is unavailable' );
341 }
342
343 if ( ! $course->is_publish() ) {
344 throw new Exception( 'Course is not publish' );
345 }
346
347 if ( $course->is_free() ) {
348 throw new Exception( 'Course is free' );
349 }
350
351 if ( $course->get_external_link() ) {
352 throw new Exception( 'Course is type external, so can not purchase' );
353 }
354
355 // 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' )
369 );
370
371 if ( $message ) {
372 learn_press_display_message( $message );
373 }
374
375 throw new Exception( $message );
376 }
377
378 // If the order contains course is processing
379 $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 );
391 }
392
393 if ( $this->has_purchased_course( $course_id ) ) {
394 throw new Exception( 'Course is purchased' );
395 }
396
397 $is_blocked_course = 0 === $course->timestamp_remaining_duration();
398 $is_enrolled_course = $this->has_enrolled_course( $course_id );
399 $is_finished_course = $this->has_finished_course( $course_id );
400
401 if ( $course->allow_repurchase() ) {
402 if ( $is_enrolled_course && ! $is_blocked_course ) {
403 throw new Exception( 'Course is enrolled' );
404 }
405 } else {
406 if ( $this->has_enrolled_or_finished( $course_id ) ) {
407 throw new Exception( 'Course is enrolled' );
408 }
409 }
410 } catch ( Exception $e ) {
411 $can_purchase = false;
412 }
413
414 return apply_filters( 'learn-press/user/can-purchase-course', $can_purchase, $this->get_id(), $course_id );
415 }
416
417 /**
418 * Check condition show finish course button
419 *
420 * @param $course
421 * @return array
422 * @author nhamdv
423 * @editor tungnx
424 * @version 1.0.2
425 */
426 public function can_show_finish_course_btn( $course ): array {
427 $return = array(
428 'status' => 'success',
429 'message' => '',
430 );
431
432 try {
433 if ( ! $course ) {
434 throw new Exception( esc_html__( 'Error: No Course or User available.', 'learnpress' ) );
435 }
436
437 $course_id = $course->get_id();
438
439 if ( $this->has_finished_course( $course_id ) ) {
440 throw new Exception( esc_html__( 'The course has finished.', 'learnpress' ) );
441 }
442
443 if ( ! $this->has_enrolled_course( $course_id ) ) {
444 throw new Exception( esc_html__( 'The course is not enrolled.', 'learnpress' ) );
445 }
446
447 if ( ! $this->is_course_in_progress( $course_id ) ) {
448 throw new Exception( esc_html__( 'Error: The course is not in progress.', 'learnpress' ) );
449 }
450
451 $course_data = $this->get_course_data( $course_id );
452
453 if ( $course_data ) {
454 $course_result = $course_data->get_result();
455
456 if ( ! $course_result['pass'] ) {
457 // Get option Can finish course if completed all item without pass
458 $can_finish = get_post_meta( $course_id, '_lp_has_finish', true ) ?? 'yes';
459
460 if ( $can_finish == 'yes' ) {
461 // Check completed all items
462 $is_all_completed = $this->is_completed_all_items( $course_id );
463 if ( ! $is_all_completed ) {
464 throw new Exception( 'All items not completed and Course not pass' );
465 }
466 } else {
467 throw new Exception( 'Course not pass' );
468 }
469 }
470 }
471
472 if ( ! apply_filters( 'lp_can_finish_course', true ) ) {
473 throw new Exception( esc_html__( 'Error: Filter the disabled finished courses.', 'learnpress' ) );
474 }
475 } catch ( Exception $e ) {
476 $return['status'] = 'false';
477 $return['message'] = $e->getMessage();
478 }
479
480 return $return;
481 }
482
483 /**
484 * Start quiz for the user.
485 *
486 * @param int $quiz_id
487 * @param int $course_id
488 * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
489 *
490 * @return LP_User_Item_Quiz|bool|WP_Error
491 * @throws Exception
492 */
493 public function start_quiz( int $quiz_id, int $course_id = 0, bool $wp_error = false ) {
494 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();
501 }
502
503 // Validate course and quiz
504 $course_id = $this->_verify_course_item( $quiz_id, $course_id );
505 if ( ! $course_id ) {
506 throw new Exception(
507 __( 'The course does not exist or does not contain a quiz.', 'learnpress' ),
508 LP_INVALID_QUIZ_OR_COURSE
509 );
510 }
511
512 $course = learn_press_get_course( $course_id );
513
514 // If user has already finished the course
515 if ( $this->has_finished_course( $course_id ) ) {
516 throw new Exception(
517 __( 'You have already finished the course of this quiz', 'learnpress' ),
518 LP_COURSE_IS_FINISHED
519 );
520 }
521
522 if ( ! $this->has_enrolled_course( $course_id ) || ! $this->is_course_in_progress( $course_id ) ) {
523 if ( ! $course->is_no_required_enroll() ) {
524 throw new Exception(
525 __( 'Please enroll in the course before starting the quiz.', 'learnpress' ),
526 LP_COURSE_IS_FINISHED
527 );
528 }
529 }
530
531 // Check if user has already started or completed quiz
532 if ( $this->has_item_status( array( 'started', 'completed' ), $quiz_id, $course_id ) ) {
533 throw new Exception(
534 __( 'The user has started or completed the quiz.', 'learnpress' ),
535 LP_QUIZ_HAS_STARTED_OR_COMPLETED
536 );
537 }
538 $user = learn_press_get_current_user();
539
540 if ( $user->is_guest() ) {
541 // if course required enroll => print message "You have to login for starting quiz"
542 if ( ! $course->is_no_required_enroll() ) {
543 throw new Exception( __( 'You have to log in to start the quiz.', 'learnpress' ), LP_REQUIRE_LOGIN );
544 }
545 }
546
547 /**
548 * Hook can start quiz
549 *
550 * @see learn_press_hk_before_start_quiz
551 */
552 $can_start_quiz = apply_filters(
553 'learn-press/before-start-quiz',
554 true,
555 $quiz_id,
556 $course_id,
557 $this->get_id()
558 );
559
560 if ( ! $can_start_quiz ) {
561 return false;
562 }
563
564 $user_quiz = learn_press_user_start_quiz( $quiz_id, false, $course_id, $wp_error );
565
566 /**
567 * Hook quiz started
568 *
569 * @since 3.0.0
570 */
571 do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
572
573 // $return = $user_quiz->get_mysql_data();
574 $return = $user_quiz;
575 } catch ( Exception $ex ) {
576 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
577 }
578
579 return $return;
580 }
581
582 /**
583 * Finish a quiz for the user and save all data needed
584 *
585 * @param int $quiz_id
586 * @param int $course_id
587 * @param bool $wp_error
588 *
589 * @return LP_User_Item_Quiz|bool|WP_Error
590 */
591 public function finish_quiz( int $quiz_id, int $course_id, bool $wp_error = false ) {
592 $return = false;
593
594 try {
595 // If user has already finished the course
596 if ( $this->has_finished_course( $course_id ) ) {
597 throw new Exception(
598 __( 'The user has already finished the course of this quiz.', 'learnpress' ),
599 LP_COURSE_IS_FINISHED
600 );
601
602 }
603
604 // Check if user has already started or completed quiz
605 if ( $this->has_item_status( array( 'completed' ), $quiz_id, $course_id ) ) {
606 throw new Exception(
607 __( 'The user has completed the quiz', 'learnpress' ),
608 LP_QUIZ_HAS_STARTED_OR_COMPLETED
609 );
610 }
611
612 /**
613 * @var LP_User_Item_Quiz $user_quiz
614 */
615 $user_quiz = $this->get_item_data( $quiz_id, $course_id );
616 $user_quiz->complete();
617
618 do_action( 'learn-press/user/quiz-finished', $quiz_id, $course_id, $this->get_id() );
619 } catch ( Exception $ex ) {
620 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : true;
621 }
622
623 return $return;
624 }
625
626 /**
627 * Retake a quiz for the user
628 *
629 * @param int $quiz_id
630 * @param int $course_id
631 * @param bool $wp_error
632 *
633 * @return bool|WP_Error|LP_User_Item_Quiz
634 *
635 * @throws Exception
636 */
637 public function retake_quiz( int $quiz_id, int $course_id, bool $wp_error = false ) {
638 $return = false;
639
640 try {
641 $course_id = $this->_verify_course_item( $quiz_id, $course_id );
642
643 if ( false === $course_id ) {
644 throw new Exception(
645 sprintf(
646 __(
647 'The course does not exist or does not contain a quiz.',
648 'learnpress'
649 ),
650 __CLASS__,
651 __FUNCTION__
652 ),
653 LP_INVALID_QUIZ_OR_COURSE
654 );
655 }
656
657 // If user has already finished the course.
658 if ( $this->has_finished_course( $course_id ) ) {
659 throw new Exception(
660 sprintf(
661 __( 'You can not redo a quiz in a finished course.', 'learnpress' ),
662 __CLASS__,
663 __FUNCTION__
664 ),
665 LP_COURSE_IS_FINISHED
666 );
667
668 }
669
670 // Check if user has already started or completed quiz
671 if ( ! $this->has_item_status( array( 'completed' ), $quiz_id, $course_id ) ) {
672 throw new Exception(
673 sprintf(
674 __( '%1$s::%2$s - The ser has not completed the quiz.', 'learnpress' ),
675 __CLASS__,
676 __FUNCTION__
677 ),
678 LP_QUIZ_HAS_STARTED_OR_COMPLETED
679 );
680 }
681
682 $allow_attempts = learn_press_get_quiz_max_retrying( $quiz_id, $course_id );
683
684 if ( ! $this->has_retake_quiz( $quiz_id, $course_id ) ) {
685 throw new Exception(
686 sprintf(
687 __( '%1$s::%2$s - Your quiz can\'t be retaken.', 'learnpress' ),
688 __CLASS__,
689 __FUNCTION__
690 ),
691 LP_QUIZ_HAS_STARTED_OR_COMPLETED
692 );
693 }
694
695 $return = learn_press_user_retake_quiz( $quiz_id, false, $course_id, $wp_error );
696
697 do_action( 'learn-press/user/quiz-retried', $quiz_id, $course_id, $this->get_id() );
698 } catch ( Exception $ex ) {
699 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
700 do_action( 'learn-press/user/retake-quiz-failure', $quiz_id, $course_id, $this->get_id() );
701 }
702
703 return $return;
704 }
705
706 /**
707 * Get quiz's user learning or completed
708 *
709 * @param LP_User_Items_Filter $filter
710 *
711 * @return LP_Query_List_Table
712 */
713 public function get_user_quizzes( LP_User_Items_Filter $filter ): LP_Query_List_Table {
714 $quizzes = [
715 'total' => 0,
716 'items' => [],
717 'pages' => 0,
718 ];
719
720 try {
721 $user_quizzes = LP_User_Items_DB::getInstance()->get_user_quizzes( $filter );
722
723 if ( $user_quizzes ) {
724 $count = LP_User_Items_DB::getInstance()->wpdb->get_var( 'SELECT FOUND_ROWS()' );
725
726 $quizzes['total'] = $count;
727 $quizzes['pages'] = ceil( $count / $filter->limit );
728
729 foreach ( $user_quizzes as $item ) {
730 $quizzes['items'][] = new LP_User_Item_Quiz( $item );
731 }
732 }
733
734 $quizzes['single'] = __( 'quiz', 'learnpress' );
735 $quizzes['plural'] = __( 'quizzes', 'learnpress' );
736 } catch ( Throwable $e ) {
737 error_log( __FUNCTION__ . ': ' . $e->getMessage() );
738 }
739
740 return new LP_Query_List_Table( $quizzes );
741 }
742
743 /**
744 * Set item is viewing in single course.
745 *
746 * @param LP_Course_Item $item
747 *
748 * @return int|LP_Course_Item
749 * @since 4.1.6.9 - move from LP_Course
750 * @editor tungnx
751 * @version 1.0.0
752 */
753 public function set_viewing_item( LP_Course_Item $item ) {
754 $flag = false;
755
756 try {
757 $user = learn_press_get_current_user();
758 if ( $user instanceof LP_User_Guest ) {
759 return $flag;
760 }
761
762 $course_id = $item->get_course_id();
763 $item_id = $item->get_id();
764 $course_data = $this->get_course_data( $course_id );
765
766 if ( $course_data && $course_data->is_enrolled() ) {
767 $item = $course_data->get_item( $item_id );
768
769 if ( ! $item ) {
770 $item = LP_User_Item::get_item_object( $item_id );
771
772 if ( ! $item ) {
773 return $flag;
774 }
775
776 if ( $item instanceof LP_User_Item_Quiz ) {
777 return $flag;
778 }
779
780 $item->set_ref_id( $course_id );
781 $item->set_parent_id( $course_data->get_user_item_id() );
782
783 $flag = $item->update();
784 }
785 }
786 } catch ( Throwable $e ) {
787 error_log( $e->getMessage() );
788 }
789
790 return $flag;
791 }
792 }
793