PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7
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.1.7, at inc/user/class-lp-user.php

795 lines 20.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_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 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 login, enroll 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 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 'Content of this item has blocked because the course has exceeded 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 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
163 if ( $user_course_data instanceof LP_User_Item_Course ) {
164 $retaken = $user_course_data->get_retaken_count();
165 $can_retake_times = $retake_option - $retaken;
166
167 if ( $can_retake_times > 0 ) {
168 $flag = $can_retake_times;
169 }
170 }
171 }
172 } catch ( Exception $e ) {
173
174 }
175
176 return apply_filters( 'learn-press/user/course/can-retry', $flag, $this->get_id(), $course_id );
177 }
178
179 /**
180 * Return true if user has already purchased course
181 *
182 * @param int $course_id
183 *
184 * @return bool
185 * @editor tungnx
186 * @modify 4.1.3
187 * @throws Exception
188 */
189 public function has_purchased_course( int $course_id ): bool {
190 $user_course = $this->get_course_data( $course_id );
191
192 return apply_filters( 'learn-press/user-purchased-course', $user_course && $user_course->is_purchased(), $course_id, $this->get_id() );
193 }
194
195 /**
196 * Check course is enrolled
197 *
198 * @param integer $course_id Course ID
199 * @param boolean $return_bool
200 * @return bool|object
201 * @editor tungnx
202 * @since 4.1.2
203 * @version 1.0.2
204 *
205 * @author Nhamdv
206 */
207 public function has_enrolled_course( int $course_id, bool $return_bool = true ) {
208 $result_check = new stdClass();
209 $result_check->check = true;
210 $result_check->message = '';
211
212 try {
213 /*$order = $this->get_course_order( $course_id );
214
215 if ( ! $order || ! $order->is_completed() ) {
216 throw new Exception( esc_html__( 'Order is not completed', 'learnpress' ) );
217 }*/
218
219 $user_course = $this->get_course_data( $course_id );
220
221 if ( ! $user_course || ! $user_course->is_enrolled() ) {
222 throw new Exception( esc_html__( 'Course is not enrolled', 'learnpress' ) );
223 }
224 } catch ( Throwable $th ) {
225 $result_check->check = false;
226 $result_check->message = $th->getMessage();
227 }
228
229 return apply_filters( 'learn-press/user/is-course-enrolled', $return_bool ? $result_check->check : $result_check, $course_id, $return_bool );
230 }
231
232 /**
233 * Return true if user has finished a course
234 *
235 * @param int $course_id .
236 *
237 * @return bool
238 * @throws Exception
239 */
240 public function has_finished_course( int $course_id ) : bool {
241 $user_course = $this->get_course_data( $course_id );
242
243 return apply_filters( 'learn-press/user-has-finished-course', $user_course && $user_course->is_finished(), $this->get_id(), $course_id );
244 }
245
246 /**
247 * Check course of user is enrolled or finished
248 *
249 * @param int $course_id
250 *
251 * @return bool
252 */
253 public function has_enrolled_or_finished( int $course_id ): bool {
254 $status = true;
255
256 try {
257 $user_course = $this->get_course_data( $course_id );
258
259 if ( ! $user_course ) {
260 $status = false;
261 } elseif ( ! $user_course->is_enrolled() && ! $user_course->is_finished() ) {
262 $status = false;
263 }
264 } catch ( Throwable $e ) {
265 $status = false;
266 }
267
268 return apply_filters( 'learn-press/user-has-finished-course', $status, $this->get_id(), $course_id );
269 }
270
271 /**
272 * Check user can enroll course
273 *
274 * @param int $course_id
275 * @param bool $return_bool
276 * @return mixed|object|bool
277 */
278 public function can_enroll_course( int $course_id, bool $return_bool = true ) {
279 $course = learn_press_get_course( $course_id );
280 $output = new stdClass();
281 $output->check = true;
282 $output->message = '';
283
284 try {
285 if ( ! $course ) {
286 throw new Exception( esc_html__( 'No Course or User available', 'learnpress' ) );
287 }
288
289 if ( ! $course->is_publish() ) {
290 throw new Exception( esc_html__( 'Course is not public', 'learnpress' ) );
291 }
292
293 if ( $course->get_external_link() && ! $this->has_purchased_course( $course_id ) ) {
294 throw new Exception( esc_html__( 'Course is External', 'learnpress' ) );
295 }
296
297 if ( ! $course->is_in_stock() ) {
298 throw new Exception( esc_html__( 'Course is full students', 'learnpress' ) );
299 }
300
301 if ( $course->is_no_required_enroll() ) {
302 throw new Exception( esc_html__( 'Course is not require enrolling.', 'learnpress' ) );
303 }
304
305 if ( ! $course->is_free() && ! $this->has_purchased_course( $course_id ) ) {
306 throw new Exception( esc_html__( 'Course is not purchased.', 'learnpress' ) );
307 }
308
309 if ( $this->has_enrolled_course( $course_id ) ) {
310 throw new Exception( esc_html__( 'This course is already enrolled.', 'learnpress' ) );
311 }
312 } catch ( \Throwable $th ) {
313 $output->check = false;
314 $output->message = $th->getMessage();
315 }
316
317 if ( $return_bool ) {
318 $output = $output->check;
319 }
320
321 return apply_filters( 'learn-press/user/can-enroll-course', $output, $course, $return_bool, $this );
322 }
323
324 /**
325 * Check can show purchase course button
326 *
327 * @param int $course_id
328 * @return bool
329 * @throws Exception
330 * @author nhamdv
331 * @editor tungnx
332 * @modify 4.1.4
333 * @version 1.0.3
334 */
335 public function can_purchase_course( int $course_id = 0 ): bool {
336 $can_purchase = true;
337 $course = learn_press_get_course( $course_id );
338
339 try {
340 if ( ! $course ) {
341 throw new Exception( 'Course is unavailable' );
342 }
343
344 if ( ! $course->is_publish() ) {
345 throw new Exception( 'Course is not publish' );
346 }
347
348 if ( $course->is_free() ) {
349 throw new Exception( 'Course is free' );
350 }
351
352 if ( $course->get_external_link() ) {
353 throw new Exception( 'Course is type external, so can not purchase' );
354 }
355
356 // Course is not require enrolling.
357 if ( $course->is_no_required_enroll() ) {
358 throw new Exception( 'Course is type no required enroll' );
359 }
360
361 if ( $this->can_retry_course( $course_id ) ) {
362 throw new Exception( 'Course is has retake' );
363 }
364
365 // If course is reached limitation.
366 if ( ! $course->is_in_stock() ) {
367 $message = apply_filters(
368 'learn-press/maximum-students-reach',
369 esc_html__( 'This course is out of stock', 'learnpress' )
370 );
371
372 if ( $message ) {
373 learn_press_display_message( $message );
374 }
375
376 throw new Exception( $message );
377 }
378
379 // If the order contains course is processing
380 $order = $this->get_course_order( $course_id );
381 if ( $order && $order->get_status() === 'processing' ) {
382 $message = apply_filters(
383 'learn-press/order-processing-message',
384 __( 'Your order is waiting for processing', 'learnpress' )
385 );
386
387 if ( $message ) {
388 learn_press_display_message( $message );
389 }
390
391 throw new Exception( $message );
392 }
393
394 if ( $this->has_purchased_course( $course_id ) ) {
395 throw new Exception( 'Course is purchased' );
396 }
397
398 $is_blocked_course = 0 === $course->timestamp_remaining_duration();
399 $is_enrolled_course = $this->has_enrolled_course( $course_id );
400 $is_finished_course = $this->has_finished_course( $course_id );
401
402 if ( $course->allow_repurchase() ) {
403 if ( $is_enrolled_course && ! $is_blocked_course ) {
404 throw new Exception( 'Course is enrolled' );
405 }
406 } else {
407 if ( $this->has_enrolled_or_finished( $course_id ) ) {
408 throw new Exception( 'Course is enrolled' );
409 }
410 }
411 } catch ( Exception $e ) {
412 $can_purchase = false;
413 }
414
415 return apply_filters( 'learn-press/user/can-purchase-course', $can_purchase, $this->get_id(), $course_id );
416 }
417
418 /**
419 * Check condition show finish course button
420 *
421 * @param $course
422 * @return array
423 * @author nhamdv
424 * @editor tungnx
425 * @version 1.0.2
426 */
427 public function can_show_finish_course_btn( $course ): array {
428 $return = array(
429 'status' => 'success',
430 'message' => '',
431 );
432
433 try {
434 if ( ! $course ) {
435 throw new Exception( esc_html__( 'Error: No Course or User available.', 'learnpress' ) );
436 }
437
438 $course_id = $course->get_id();
439
440 if ( $this->has_finished_course( $course_id ) ) {
441 throw new Exception( esc_html__( 'Course is has finished.', 'learnpress' ) );
442 }
443
444 if ( ! $this->has_enrolled_course( $course_id ) ) {
445 throw new Exception( esc_html__( 'Course is not enroll.', 'learnpress' ) );
446 }
447
448 if ( ! $this->is_course_in_progress( $course_id ) ) {
449 throw new Exception( esc_html__( 'Error: Course is not in-progress.', 'learnpress' ) );
450 }
451
452 $course_data = $this->get_course_data( $course_id );
453
454 if ( $course_data ) {
455 $course_result = $course_data->get_result();
456
457 if ( ! $course_result['pass'] ) {
458 // Get option Can finish course if completed all item without pass
459 $can_finish = get_post_meta( $course_id, '_lp_has_finish', true ) ?? 'yes';
460
461 if ( $can_finish == 'yes' ) {
462 // Check completed all items
463 $is_all_completed = $this->is_completed_all_items( $course_id );
464 if ( ! $is_all_completed ) {
465 throw new Exception( 'All items not completed and Course not pass' );
466 }
467 } else {
468 throw new Exception( 'Course not pass' );
469 }
470 }
471 }
472
473 if ( ! apply_filters( 'lp_can_finish_course', true ) ) {
474 throw new Exception( esc_html__( 'Error: Filter disable finish course.', 'learnpress' ) );
475 }
476 } catch ( Exception $e ) {
477 $return['status'] = 'false';
478 $return['message'] = $e->getMessage();
479 }
480
481 return $return;
482 }
483
484 /**
485 * Start quiz for the user.
486 *
487 * @param int $quiz_id
488 * @param int $course_id
489 * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
490 *
491 * @return LP_User_Item_Quiz|bool|WP_Error
492 * @throws Exception
493 */
494 public function start_quiz( int $quiz_id, int $course_id = 0, bool $wp_error = false ) {
495 try {
496 $item_id = learn_press_get_request( 'lp-preview' );
497
498 if ( $item_id ) {
499 learn_press_add_message( __( 'You cannot start a quiz in preview mode.', 'learnpress' ), 'error' );
500 wp_safe_redirect( learn_press_get_preview_url( $item_id ) );
501 exit();
502 }
503
504 // Validate course and quiz
505 $course_id = $this->_verify_course_item( $quiz_id, $course_id );
506 if ( ! $course_id ) {
507 throw new Exception(
508 __( 'Course does not exist or does not contain the quiz', 'learnpress' ),
509 LP_INVALID_QUIZ_OR_COURSE
510 );
511 }
512
513 $course = learn_press_get_course( $course_id );
514 //$access_level = $this->get_course_access_level( $course_id );
515
516 // If user has already finished the course
517 if ( $this->has_finished_course( $course_id ) ) {
518 throw new Exception(
519 __( 'You have already finished the course of this quiz', 'learnpress' ),
520 LP_COURSE_IS_FINISHED
521 );
522 }
523
524 if ( ! $this->has_enrolled_course( $course_id ) || ! $this->is_course_in_progress( $course_id ) ) {
525 if ( ! $course->is_no_required_enroll() ) {
526 throw new Exception(
527 __( 'Please enroll course before starting quiz.', 'learnpress' ),
528 LP_COURSE_IS_FINISHED
529 );
530 }
531 }
532
533 // Check if user has already started or completed quiz
534 if ( $this->has_item_status( array( 'started', 'completed' ), $quiz_id, $course_id ) ) {
535 throw new Exception(
536 __( 'User has started or completed quiz', 'learnpress' ),
537 LP_QUIZ_HAS_STARTED_OR_COMPLETED
538 );
539 }
540 $user = learn_press_get_current_user();
541
542 if ( $user->is_guest() ) {
543 // if course required enroll => print message "You have to login for starting quiz"
544 if ( ! $course->is_no_required_enroll() ) {
545 throw new Exception( __( 'You have to login for starting quiz.', 'learnpress' ), LP_REQUIRE_LOGIN );
546 }
547 }
548
549 /**
550 * Hook can start quiz
551 *
552 * @see learn_press_hk_before_start_quiz
553 */
554 $can_start_quiz = apply_filters(
555 'learn-press/before-start-quiz',
556 true,
557 $quiz_id,
558 $course_id,
559 $this->get_id()
560 );
561
562 if ( ! $can_start_quiz ) {
563 return false;
564 }
565
566 $user_quiz = learn_press_user_start_quiz( $quiz_id, false, $course_id, $wp_error );
567
568 /**
569 * Hook quiz started
570 *
571 * @since 3.0.0
572 */
573 do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
574
575 // $return = $user_quiz->get_mysql_data();
576 $return = $user_quiz;
577 } catch ( Exception $ex ) {
578 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
579 }
580
581 return $return;
582 }
583
584 /**
585 * Finish a quiz for the user and save all data needed
586 *
587 * @param int $quiz_id
588 * @param int $course_id
589 * @param bool $wp_error
590 *
591 * @return LP_User_Item_Quiz|bool|WP_Error
592 */
593 public function finish_quiz( int $quiz_id, int $course_id, bool $wp_error = false ) {
594 $return = false;
595
596 try {
597 // If user has already finished the course
598 if ( $this->has_finished_course( $course_id ) ) {
599 throw new Exception(
600 __( 'User has already finished course of this quiz', 'learnpress' ),
601 LP_COURSE_IS_FINISHED
602 );
603
604 }
605
606 // Check if user has already started or completed quiz
607 if ( $this->has_item_status( array( 'completed' ), $quiz_id, $course_id ) ) {
608 throw new Exception(
609 __( 'User has completed quiz', 'learnpress' ),
610 LP_QUIZ_HAS_STARTED_OR_COMPLETED
611 );
612 }
613
614 /**
615 * @var LP_User_Item_Quiz $user_quiz
616 */
617 $user_quiz = $this->get_item_data( $quiz_id, $course_id );
618 $user_quiz->complete();
619
620 do_action( 'learn-press/user/quiz-finished', $quiz_id, $course_id, $this->get_id() );
621 } catch ( Exception $ex ) {
622 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : true;
623 }
624
625 return $return;
626 }
627
628 /**
629 * Retake a quiz for the user
630 *
631 * @param int $quiz_id
632 * @param int $course_id
633 * @param bool $wp_error
634 *
635 * @return bool|WP_Error|LP_User_Item_Quiz
636 *
637 * @throws Exception
638 */
639 public function retake_quiz( int $quiz_id, int $course_id, bool $wp_error = false ) {
640 $return = false;
641
642 try {
643 $course_id = $this->_verify_course_item( $quiz_id, $course_id );
644
645 if ( false === $course_id ) {
646 throw new Exception(
647 sprintf(
648 __(
649 'Course does not exist or does not contain the quiz.',
650 'learnpress'
651 ),
652 __CLASS__,
653 __FUNCTION__
654 ),
655 LP_INVALID_QUIZ_OR_COURSE
656 );
657 }
658
659 // If user has already finished the course.
660 if ( $this->has_finished_course( $course_id ) ) {
661 throw new Exception(
662 sprintf(
663 __( 'You can not redo a quiz in a finished course.', 'learnpress' ),
664 __CLASS__,
665 __FUNCTION__
666 ),
667 LP_COURSE_IS_FINISHED
668 );
669
670 }
671
672 // Check if user has already started or completed quiz
673 if ( ! $this->has_item_status( array( 'completed' ), $quiz_id, $course_id ) ) {
674 throw new Exception(
675 sprintf(
676 __( '%1$s::%2$s - User has not completed quiz.', 'learnpress' ),
677 __CLASS__,
678 __FUNCTION__
679 ),
680 LP_QUIZ_HAS_STARTED_OR_COMPLETED
681 );
682 }
683
684 $allow_attempts = learn_press_get_quiz_max_retrying( $quiz_id, $course_id );
685
686 if ( ! $this->has_retake_quiz( $quiz_id, $course_id ) ) {
687 throw new Exception(
688 sprintf(
689 __( '%1$s::%2$s - Your Quiz can\'t retake.', 'learnpress' ),
690 __CLASS__,
691 __FUNCTION__
692 ),
693 LP_QUIZ_HAS_STARTED_OR_COMPLETED
694 );
695 }
696
697 $return = learn_press_user_retake_quiz( $quiz_id, false, $course_id, $wp_error );
698
699 do_action( 'learn-press/user/quiz-retried', $quiz_id, $course_id, $this->get_id() );
700 } catch ( Exception $ex ) {
701 $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
702 do_action( 'learn-press/user/retake-quiz-failure', $quiz_id, $course_id, $this->get_id() );
703 }
704
705 return $return;
706 }
707
708 /**
709 * Get quiz's user learning or completed
710 *
711 * @param LP_User_Items_Filter $filter
712 *
713 * @return LP_Query_List_Table
714 */
715 public function get_user_quizzes( LP_User_Items_Filter $filter ): LP_Query_List_Table {
716 $quizzes = [
717 'total' => 0,
718 'items' => [],
719 'pages' => 0,
720 ];
721
722 try {
723 $user_quizzes = LP_User_Items_DB::getInstance()->get_user_quizzes( $filter );
724
725 if ( $user_quizzes ) {
726 $count = LP_User_Items_DB::getInstance()->wpdb->get_var( 'SELECT FOUND_ROWS()' );
727
728 $quizzes['total'] = $count;
729 $quizzes['pages'] = ceil( $count / $filter->limit );
730
731 foreach ( $user_quizzes as $item ) {
732 $quizzes['items'][] = new LP_User_Item_Quiz( $item );
733 }
734 }
735
736 $quizzes['single'] = __( 'quiz', 'learnpress' );
737 $quizzes['plural'] = __( 'quizzes', 'learnpress' );
738 } catch ( Throwable $e ) {
739 error_log( __FUNCTION__ . ': ' . $e->getMessage() );
740 }
741
742 return new LP_Query_List_Table( $quizzes );
743 }
744
745 /**
746 * Set item is viewing in single course.
747 *
748 * @param LP_Course_Item $item
749 *
750 * @return int|LP_Course_Item
751 * @since 4.1.6.9 - move from LP_Course
752 * @editor tungnx
753 * @version 1.0.0
754 */
755 public function set_viewing_item( LP_Course_Item $item ) {
756 $flag = false;
757
758 try {
759 $user = learn_press_get_current_user();
760 if ( $user instanceof LP_User_Guest ) {
761 return $flag;
762 }
763
764 $course_id = $item->get_course_id();
765 $item_id = $item->get_id();
766 $course_data = $this->get_course_data( $course_id );
767
768 if ( $course_data && $course_data->is_enrolled() ) {
769 $item = $course_data->get_item( $item_id );
770
771 if ( ! $item ) {
772 $item = LP_User_Item::get_item_object( $item_id );
773
774 if ( ! $item ) {
775 return $flag;
776 }
777
778 if ( $item instanceof LP_User_Item_Quiz ) {
779 return $flag;
780 }
781
782 $item->set_ref_id( $course_id );
783 $item->set_parent_id( $course_data->get_user_item_id() );
784
785 $flag = $item->update();
786 }
787 }
788 } catch ( Throwable $e ) {
789 error_log( $e->getMessage() );
790 }
791
792 return $flag;
793 }
794 }
795