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/templates/class-lp-template-course.php +1053 -1056 4.3.8 → 4.4.9 View file →
@@ -1,1056 +1,1053 @@
1 -<?php
2 -
3 -use LearnPress\Helpers\Template;
4 -use LearnPress\Models\CourseModel;
5 -use LearnPress\Models\UserItems\UserCourseModel;
6 -use LearnPress\Models\UserModel;
7 -use LearnPress\TemplateHooks\Course\SingleCourseTemplate;
8 -use LearnPress\TemplateHooks\UserItem\UserCourseTemplate;
9 -
10 -/**
11 - * Class LP_Course_Template
12 - *
13 - * Groups templates related course and items
14 - *
15 - * @since 3.x.x
16 - */
17 -class LP_Template_Course extends LP_Abstract_Template {
18 - /**
19 - * @var LP_Course
20 - */
21 - public $course = null;
22 -
23 - /**
24 - * LP_Template_Course constructor.
25 - */
26 - public function __construct() {
27 - parent::__construct();
28 -
29 - add_action( 'the_post', array( $this, 'get_course' ) );
30 - }
31 -
32 - public function get_course() {
33 - // global $post;
34 -
35 - $this->course = learn_press_get_course();
36 - }
37 -
38 - public function course_sidebar_preview() {
39 - learn_press_get_template( 'single-course/sidebar/preview' );
40 - }
41 -
42 - public function course_buttons() {
43 - global $lp_user;
44 - $lp_user = learn_press_get_current_user();
45 - learn_press_get_template( 'single-course/buttons' );
46 - }
47 -
48 - public function course_graduation() {
49 - $user = learn_press_get_current_user();
50 - $course = learn_press_get_course();
51 -
52 - if ( ! $user || ! $course ) {
53 - return;
54 - }
55 -
56 - if ( ! $user->has_finished_course( $course->get_id() ) ) {
57 - return;
58 - }
59 -
60 - $graduation = $user->get_course_grade( $course->get_id() );
61 -
62 - learn_press_get_template( 'single-course/graduation', array( 'graduation' => $graduation ) );
63 - }
64 -
65 - /**
66 - * Show button retry course
67 - *
68 - * @throws Exception
69 - */
70 - public function button_retry( $course = null ) {
71 - _deprecated_function( __METHOD__, '4.3.2.4', 'UserCourseTemplate::html_btn_retake' );
72 - return;
73 -
74 - $user = learn_press_get_current_user();
75 - if ( empty( $course ) ) {
76 - $course = learn_press_get_course();
77 - }
78 -
79 - if ( ! $user || ! $course ) {
80 - return;
81 - }
82 -
83 - $can_retake_times = $user->can_retry_course( $course->get_id() );
84 -
85 - // Course has no items
86 - if ( empty( $course->count_items() ) ) {
87 - return;
88 - }
89 -
90 - if ( $can_retake_times ) {
91 - learn_press_get_template(
92 - 'single-course/buttons/retry',
93 - array( 'can_retake_times' => $can_retake_times )
94 - );
95 - }
96 - }
97 -
98 - public function course_media_preview() {
99 - $course = learn_press_get_course();
100 -
101 - echo wp_kses_post( $course->get_image() );
102 - }
103 -
104 - /**
105 - * @param LP_Quiz $item
106 - */
107 - public function quiz_meta_questions( $item ) {
108 - $count = $item->count_questions();
109 - printf(
110 - '<span class="item-meta count-questions">%s</span>',
111 - sprintf( _n( '%1$d question', '%1$d questions', $count, 'learnpress' ), $count )
112 - );
113 - }
114 -
115 - /**
116 - * @param LP_Quiz|LP_Lesson $item
117 - */
118 - public function item_meta_duration( $item ) {
119 - $duration = learn_press_get_post_translated_duration( $item->get_id(), false );
120 -
121 - if ( $duration ) {
122 - echo '<span class="item-meta duration">' . $duration . '</span>';
123 - }
124 - }
125 -
126 - /**
127 - * @var LP_Course_Item $item
128 - */
129 - public function quiz_meta_final( $item ) {
130 - $course = $item->get_course();
131 -
132 - if ( ! $course || ! $course->is_final_quiz( $item->get_id() )
133 - || $course->get_evaluation_type() != 'evaluate_final_quiz' ) {
134 - return;
135 - }
136 -
137 - echo '<span class="item-meta final-quiz">' . esc_html__( 'Final', 'learnpress' ) . '</span>';
138 - }
139 -
140 - public function course_button() {
141 - echo '[COURSE BUTTON]';
142 - }
143 -
144 - public function course_title() {
145 - echo '[COURSE TITLE]';
146 - }
147 -
148 - public function courses_top_bar() {
149 - learn_press_get_template( 'courses-top-bar' );
150 - }
151 -
152 - /**
153 - * Display price or free of course, not button, it is label.
154 - *
155 - * @return void
156 - * @since 4.0.0
157 - * @version 1.0.3
158 - */
159 - public function course_pricing() {
160 - $course = learn_press_get_course();
161 - $user = learn_press_get_current_user();
162 -
163 - $courseModel = CourseModel::find( $course->get_id(), true );
164 - $can_purchase = $courseModel->can_purchase( UserModel::find( $user->get_id(), true ) );
165 - $userCourseModel = UserCourseModel::find( $user->get_id(), $course->get_id(), true );
166 - if ( get_current_user_id() ) {
167 - if ( $userCourseModel ) {
168 - if ( $userCourseModel->has_enrolled() ) {
169 - return;
170 - } elseif ( $can_purchase instanceof WP_Error ) {
171 - return;
172 - }
173 - }
174 - }
175 -
176 - $price_html = $course->get_course_price_html();
177 - learn_press_get_template( 'single-course/price', compact( 'course', 'user', 'price_html' ) );
178 - }
179 -
180 - /**
181 - * Template purchase course button
182 - *
183 - * @editor tungnx
184 - * @modify 4.1.3.1
185 - * @throws Exception
186 - * @version 4.0.2
187 - */
188 - public function course_purchase_button( $course = null ) {
189 - _deprecated_function( __METHOD__, '4.3.2', 'SingleCourseTemplate::html_btn_purchase_course' );
190 - return;
191 -
192 - $singleCourseTemplate = SingleCourseTemplate::instance();
193 - $course = CourseModel::find( get_the_ID(), true );
194 - $user = UserModel::find( get_current_user_id(), true );
195 - echo $singleCourseTemplate->html_btn_purchase_course( $course, $user );
196 - }
197 -
198 - /**
199 - * Show button enroll course
200 - *
201 - * @editor tungnx
202 - * @modify 4.1.3.1
203 - * @throws Exception
204 - * @version 4.0.3
205 - */
206 - public function course_enroll_button( $course = null ) {
207 - _deprecated_function( __METHOD__, '4.3.2.4', 'SingleCourseTemplate::html_btn_enroll_course' );
208 - return;
209 -
210 - $singleCourseTemplate = SingleCourseTemplate::instance();
211 - $course = CourseModel::find( get_the_ID(), true );
212 - $user = UserModel::find( get_current_user_id(), true );
213 - echo $singleCourseTemplate->html_btn_enroll_course( $course, $user );
214 - return;
215 -
216 - $can_show = true;
217 - $user = learn_press_get_current_user();
218 - if ( empty( $course ) ) {
219 - $course = learn_press_get_course();
220 - }
221 - $error_code = '';
222 -
223 - try {
224 - if ( ! $course || ! $user ) {
225 - throw new Exception( 'User or Course is not exists' );
226 - }
227 -
228 - // User can not enroll course.
229 - $can_enroll_course = $user->can_enroll_course( $course->get_id(), false );
230 - if ( ! $can_enroll_course->check ) {
231 - $error_code = $can_enroll_course->code;
232 - throw new Exception( $can_enroll_course->message );
233 - }
234 -
235 - if ( $user->has_finished_course( $course->get_id() ) ) {
236 - $error_code = 'course_is_finished';
237 - throw new Exception( __( 'Course is finished', 'learnpress' ) );
238 - }
239 - } catch ( Throwable $e ) {
240 - if ( ! in_array( $error_code, [ 'course_is_enrolled', 'course_can_retry' ] ) ) {
241 - if ( $course && $course->is_free() ) {
242 - Template::print_message( $e->getMessage(), 'warning' );
243 - }
244 - }
245 - $can_show = false;
246 - }
247 -
248 - $can_show = apply_filters( 'learnpress/course/template/button-enroll/can-show', $can_show, $user, $course );
249 - if ( ! $can_show ) {
250 - return;
251 - }
252 -
253 - $args = array(
254 - 'user' => $user,
255 - 'course' => $course,
256 - );
257 -
258 - learn_press_get_template( 'single-course/buttons/enroll.php', $args );
259 - }
260 -
261 - public function course_extra_requirements( $course_id ) {
262 - $course = LP_Course::get_course( $course_id );
263 - if ( ! $course ) {
264 - return;
265 - }
266 -
267 - $requirements = apply_filters(
268 - 'learn-press/course-extra-requirements',
269 - $course->get_extra_info( 'requirements' ),
270 - $course_id
271 - );
272 -
273 - if ( ! $requirements ) {
274 - return;
275 - }
276 -
277 - learn_press_get_template(
278 - 'single-course/sidebar/course-extra',
279 - array(
280 - 'type' => 'requirements',
281 - 'title' => esc_html__( 'Requirements', 'learnpress' ),
282 - 'content' => $requirements,
283 - )
284 - );
285 - }
286 -
287 - public function course_extra_key_features( $course_id ) {
288 - $course = LP_Course::get_course( $course_id );
289 - if ( ! $course ) {
290 - return;
291 - }
292 -
293 - $key_features = apply_filters(
294 - 'learn-press/course-extra-key-features',
295 - $course->get_extra_info( 'key_features' ),
296 - $course_id
297 - );
298 -
299 - if ( ! $key_features ) {
300 - return;
301 - }
302 -
303 - learn_press_get_template(
304 - 'single-course/sidebar/course-extra',
305 - array(
306 - 'type' => 'key-features',
307 - 'title' => esc_html__( 'Key features', 'learnpress' ),
308 - 'content' => $key_features,
309 - )
310 - );
311 - }
312 -
313 - public function course_extra_target_audiences( $course_id ) {
314 - $course = LP_Course::get_course( $course_id );
315 - if ( ! $course ) {
316 - return;
317 - }
318 -
319 - $target_audiences = apply_filters(
320 - 'learn-press/course-extra-target-audiences',
321 - $course->get_extra_info( 'target_audiences' ),
322 - $course_id
323 - );
324 -
325 - if ( ! $target_audiences ) {
326 - return;
327 - }
328 -
329 - learn_press_get_template(
330 - 'single-course/sidebar/course-extra',
331 - array(
332 - 'type' => 'target-audiences',
333 - 'title' => esc_html__( 'Target audiences', 'learnpress' ),
334 - 'content' => $target_audiences,
335 - )
336 - );
337 - }
338 -
339 - /**
340 - * Show template "continue" button con single course
341 - *
342 - * @throws Exception
343 - * @modify 4.1.3.1
344 - * @version 4.0.4
345 - * @since 4.0.0
346 - */
347 - public static function course_continue_button( $args = [] ) {
348 - _deprecated_function( __METHOD__, '4.3.2.4', 'UserCourseTemplate::html_btn_continue' );
349 - return;
350 -
351 - $course_id_param = $args['course-id'] ?? 0;
352 - $course_id = ! empty( $course_id_param ) ? $course_id_param : get_the_ID();
353 - $courseModel = CourseModel::find( $course_id, true );
354 - $user_id = get_current_user_id();
355 -
356 - try {
357 - if ( ! $user_id || ! $courseModel ) {
358 - throw new Exception( 'User or Course not exists!' );
359 - }
360 -
361 - $userCourseModel = UserCourseModel::find( $user_id, $courseModel->get_id(), true );
362 - if ( ! $userCourseModel || ! $userCourseModel->has_enrolled() ) {
363 - throw new Exception( 'User not enrolled course' );
364 - }
365 -
366 - if ( $userCourseModel->has_finished() ) {
367 - throw new Exception( 'User has finished course' );
368 - }
369 -
370 - // Course has no items
371 - if ( empty( $courseModel->get_total_items() ) ) {
372 - throw new Exception( 'Course no any item' );
373 - }
374 -
375 - // Do not display continue button if course is block duration
376 - if ( $userCourseModel->timestamp_remaining_duration() === 0 ) {
377 - throw new Exception( 'Course is blocked' );
378 - }
379 -
380 - $section = [
381 - 'start' => '<div>',
382 - 'link' => UserCourseTemplate::instance()->html_btn_continue( $userCourseModel ),
383 - 'end' => '</div>',
384 - ];
385 -
386 - echo Template::combine_components( $section );
387 - } catch ( Throwable $e ) {
388 -
389 - }
390 - }
391 -
392 - public function course_finish_button( $course = null ) {
393 - _deprecated_function( __METHOD__, '4.3.2.4', 'UserCourseTemplate::html_btn_finish' );
394 - return;
395 -
396 - $user = learn_press_get_current_user();
397 - if ( empty( $course ) ) {
398 - $course = learn_press_get_course();
399 - }
400 -
401 - if ( ! $course ) {
402 - return;
403 - }
404 -
405 - // Course has no items
406 - if ( empty( $course->count_items() ) ) {
407 - return;
408 - }
409 -
410 - $check = $user->can_show_finish_course_btn( $course );
411 -
412 - if ( 'success' !== $check['status'] ) {
413 - return;
414 - }
415 -
416 - learn_press_get_template(
417 - 'single-course/buttons/finish.php',
418 - array(
419 - 'course' => $course,
420 - 'user' => $user,
421 - )
422 - );
423 - }
424 -
425 - /**
426 - * Button course external link
427 - *
428 - * @throws Exception
429 - * @editor tungnx
430 - * @modify 4.1.3
431 - */
432 - public function course_external_button( $course = null ) {
433 - _deprecated_function( __METHOD__, '4.3.2.4', 'SingleCourseTemplate::html_btn_external' );
434 - return;
435 -
436 - if ( empty( $course ) ) {
437 - $course = learn_press_get_course();
438 - }
439 -
440 - $user = learn_press_get_current_user();
441 -
442 - if ( ! $course ) {
443 - return;
444 - }
445 -
446 - $link = $course->get_external_link();
447 - if ( empty( $link ) || $user->has_purchased_course( $course->get_id() ) ) {
448 - return;
449 - }
450 -
451 - $user = learn_press_get_current_user();
452 -
453 - if ( $user && ! $user->has_enrolled_or_finished( $course->get_id() ) ) {
454 - // Remove all another buttons
455 - // learn_press_remove_course_buttons();
456 - learn_press_get_template( 'single-course/buttons/external-link.php' );
457 -
458 - // Add back other buttons for other courses
459 - add_action( 'learn-press/after-course-buttons', 'learn_press_add_course_buttons' );
460 - }
461 - }
462 -
463 - public function popup_header() {
464 - $user = learn_press_get_current_user();
465 - $course = learn_press_get_course();
466 -
467 - if ( ! $user || ! $course ) {
468 - return;
469 - }
470 -
471 - $percentage = 0;
472 - $total_items = 0;
473 - $completed_items = 0;
474 - $course_data = $user->get_course_data( $course->get_id() );
475 -
476 - if ( $course_data && ! empty( $course_data->get_user_id() ) && ! $course->is_no_required_enroll() ) {
477 - $course_results = $course_data->get_result();
478 - $completed_items = $course_results['completed_items'];
479 - $total_items = $course_results['count_items'];
480 - $percentage = $course_results['count_items'] ? absint( $course_results['completed_items'] / $course_results['count_items'] * 100 ) : 0;
481 - }
482 -
483 - learn_press_get_template( 'single-course/content-item/popup-header', compact( 'user', 'course', 'total_items', 'completed_items', 'percentage' ) );
484 - }
485 -
486 - public function popup_sidebar() {
487 - learn_press_get_template( 'single-course/content-item/popup-sidebar' );
488 - }
489 -
490 - /**
491 - * Get single item's course
492 - */
493 - public function popup_content() {
494 - learn_press_get_template( 'single-course/content-item/popup-content' );
495 - }
496 -
497 - public function popup_footer() {
498 - learn_press_get_template( 'single-course/content-item/popup-footer' );
499 - }
500 -
501 - public function popup_footer_nav() {
502 - $course = learn_press_get_course();
503 - if ( ! $course ) {
504 - return;
505 - }
506 -
507 - $next_item = false;
508 - $prev_item = false;
509 -
510 - $next_id = $course->get_next_item();
511 - $prev_id = $course->get_prev_item();
512 -
513 - if ( $next_id ) {
514 - $next_item = $course->get_item( $next_id );
515 - if ( $next_item instanceof LP_Course_Item ) {
516 - $next_item->set_course( $course->get_id() );
517 - }
518 - }
519 -
520 - if ( $prev_id ) {
521 - $prev_item = $course->get_item( $prev_id );
522 - if ( $prev_item instanceof LP_Course_Item ) {
523 - $prev_item->set_course( $course->get_id() );
524 - }
525 - }
526 -
527 - if ( ! $prev_item && ! $next_item ) {
528 - return;
529 - }
530 -
531 - learn_press_get_template(
532 - 'single-course/content-item/nav.php',
533 - array(
534 - 'next_item' => $next_item,
535 - 'prev_item' => $prev_item,
536 - )
537 - );
538 - }
539 -
540 - /**
541 - * Display course curriculum.
542 - *
543 - * @since 4.1.6
544 - * @since 4.2.5.5 remove code load old template user for course curriculum load page instead of via AJAX.
545 - * @version 1.0.2
546 - * @depreacted 4.2.8.7.1
547 - */
548 - public function course_curriculum() {
549 - /**
550 - * @var CourseModel $lpCourseModel
551 - */
552 - global $lpCourseModel;
553 - $courseModel = CourseModel::find( get_the_ID(), true );
554 - if ( $lpCourseModel instanceof CourseModel ) {
555 - $courseModel = $lpCourseModel;
556 - }
557 -
558 - $course_item = LP_Global::course_item();
559 - $userModel = UserModel::find( get_current_user_id(), true );
560 -
561 - $singleCourseTemplate = SingleCourseTemplate::instance();
562 - echo $singleCourseTemplate->html_curriculum( $courseModel, $userModel );
563 - }
564 -
565 - /**
566 - * Display course curriculum.
567 - *
568 - * @since 4.1.6
569 - * @since 4.2.5.5 remove code load old template user for course curriculum load page instead of via AJAX.
570 - * @version 1.0.2
571 - */
572 - public function course_curriculum_bk() {
573 - /**
574 - * @var CourseModel $lpCourseModel
575 - */
576 - global $lpCourseModel;
577 - $course_item = LP_Global::course_item();
578 -
579 - if ( $course_item ) { // Check if current item is viewable
580 - $course_id = 0;
581 - if ( $lpCourseModel ) {
582 - $course_id = $lpCourseModel->get_id();
583 - }
584 -
585 - $item_id = (int) $course_item->get_id();
586 - $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id, $course_id );
587 - }
588 - ?>
589 - <div class="learnpress-course-curriculum" data-section="<?php echo esc_attr( $section_id ?? '' ); ?>"
590 - data-id="<?php echo esc_attr( $item_id ?? '' ); ?>">
591 - <?php lp_skeleton_animation_html( 10 ); ?>
592 - </div>
593 - <?php
594 - }
595 -
596 - /**
597 - * Get template content item's course
598 - */
599 - public function course_content_item() {
600 - learn_press_get_template( 'single-course/content-item' );
601 - }
602 -
603 - public function courses_loop_item_meta() {
604 - learn_press_get_template( 'loop/course/meta' );
605 - }
606 -
607 - public function courses_loop_item_info_begin() {
608 - learn_press_get_template( 'loop/course/info-begin' );
609 - }
610 -
611 - public function courses_loop_item_info_end() {
612 - learn_press_get_template( 'loop/course/info-end' );
613 - }
614 -
615 - public function courses_loop_item_price() {
616 - $course = learn_press_get_course();
617 - if ( ! $course ) {
618 - return;
619 - }
620 -
621 - $price_html = $course->get_course_price_html();
622 - learn_press_get_template( 'loop/course/price', compact( 'course', 'price_html' ) );
623 - }
624 -
625 - public function begin_courses_loop() {
626 - learn_press_get_template( 'loop/course/loop-begin.php' );
627 - }
628 -
629 - public function end_courses_loop() {
630 - learn_press_get_template( 'loop/course/loop-end.php' );
631 - }
632 -
633 - public function course_item_content() {
634 - $course = learn_press_get_course();
635 - if ( ! $course ) {
636 - return;
637 - }
638 -
639 - $item = LP_Global::course_item();
640 -
641 - /**
642 - * Fix only for WPBakery load style inline
643 - * custom CSS is provided, load inline style.
644 - *
645 - * @editor tuanta
646 - * @since 3.2.8.1
647 - */
648 - $shortcodes_custom_css = get_post_meta( $item->get_id(), '_wpb_shortcodes_custom_css', true );
649 -
650 - if ( ! empty( $shortcodes_custom_css ) ) {
651 - $shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
652 - echo '<style data-type="vc_shortcodes-custom-css">';
653 - echo wp_kses_post( $shortcodes_custom_css );
654 - echo '</style>';
655 - }
656 - // End
657 -
658 - $timestamp_remaining = $course->timestamp_remaining_duration();
659 - if ( $timestamp_remaining > 0 ) {
660 - echo '<input type="hidden" name="lp-course-timestamp-remaining" value="' . esc_attr( $timestamp_remaining ) . '">';
661 - }
662 - // End
663 -
664 - $item_template_name = learn_press_locate_template( 'single-course/content-item-' . $item->get_item_type() . '.php' );
665 -
666 - if ( file_exists( $item_template_name ) ) {
667 - learn_press_get_template( 'single-course/content-item-' . $item->get_item_type() . '.php' );
668 - } else {
669 - echo esc_html( sprintf( 'File %s not exists', $item_template_name ) );
670 - }
671 - }
672 -
673 - public function item_lesson_title() {
674 - $item = LP_Global::course_item();
675 - $format = $item->get_format();
676 - $format_template = learn_press_locate_template( "content-lesson/{$format}/title.php" );
677 -
678 - if ( 'standard' !== $format && file_exists( $format_template ) ) {
679 - include $format_template;
680 -
681 - return;
682 - }
683 - learn_press_get_template( 'content-lesson/title.php', array( 'lesson' => $item ) );
684 - }
685 -
686 - public function item_lesson_content() {
687 - $item = LP_Global::course_item();
688 - $format = $item->get_format();
689 - $format_template = learn_press_locate_template( "content-lesson/{$format}/content.php" );
690 -
691 - if ( 'standard' !== $format && file_exists( $format_template ) ) {
692 - include $format_template;
693 -
694 - return;
695 - }
696 - do_action( 'learn-press/lesson-start', $item );
697 -
698 - Template::instance()->get_frontend_template( 'content-lesson/content.php', array( 'lesson' => $item ) );
699 - }
700 -
701 - /**
702 - * Get template button complete lesson
703 - */
704 - public function item_lesson_complete_button() {
705 - $user = learn_press_get_current_user();
706 - $course = learn_press_get_course();
707 - if ( ! $course ) {
708 - return;
709 - }
710 -
711 - try {
712 - $item = LP_Global::course_item();
713 - if ( ! $user || ! $user->is_course_in_progress( $course->get_id() ) ) {
714 - return;
715 - }
716 -
717 - // The complete button is not displayed when the course is locked --hungkv--
718 - if ( $user->can_view_content_course( $course->get_id() )->key === LP_BLOCK_COURSE_DURATION_EXPIRE ) {
719 - return;
720 - }
721 -
722 - learn_press_get_template(
723 - 'content-lesson/button-complete.php',
724 - array(
725 - 'user' => $user,
726 - 'course' => $course,
727 - 'item' => $item,
728 - )
729 - );
730 - } catch ( Throwable $e ) {
731 - error_log( $e->getMessage() );
732 - }
733 - }
734 -
735 - public function item_lesson_material() {
736 - try {
737 - do_action( 'learn-press/course-material/layout', [] );
738 - } catch ( Throwable $e ) {
739 - error_log( $e->getMessage() );
740 - }
741 - }
742 -
743 - /**
744 - * Template show count items
745 - *
746 - * @since 4.0.0
747 - * @version 1.0.2
748 - * @editor tungnx
749 - */
750 - public function count_object() {
751 - $course = CourseModel::find( get_the_ID(), true );
752 - if ( ! $course ) {
753 - return;
754 - }
755 -
756 - $lessons = $course->count_items( LP_LESSON_CPT );
757 - $quizzes = $course->count_items( LP_QUIZ_CPT );
758 - $students = $course->count_students();
759 -
760 - $counts = apply_filters(
761 - 'learnpress/course/count/items',
762 - array(
763 - 'lesson' => sprintf(
764 - '<span class="meta-number">' . _n( '%d lesson', '%d lessons', $lessons, 'learnpress' ) . '</span>',
765 - $lessons
766 - ),
767 - 'quiz' => sprintf(
768 - '<span class="meta-number">' . _n( '%d quiz', '%d quizzes', $quizzes, 'learnpress' ) . '</span>',
769 - $quizzes
770 - ),
771 - 'student' => sprintf(
772 - '<span class="meta-number">' . _n( '%d student', '%d students', $students, 'learnpress' ) . '</span>',
773 - $students
774 - ),
775 - ),
776 - array( $lessons, $quizzes, $students )
777 - );
778 -
779 - foreach ( $counts as $object => $count ) {
780 - learn_press_get_template(
781 - 'single-course/meta/count',
782 - array(
783 - 'count' => $count,
784 - 'object' => $object,
785 - )
786 - );
787 - }
788 - }
789 -
790 - public function course_extra_boxes() {
791 - $course = LP_Course::get_course( get_the_ID() );
792 - if ( ! $course ) {
793 - return;
794 - }
795 -
796 - $boxes = apply_filters(
797 - 'learn-press/course-extra-boxes-data',
798 - array(
799 - array(
800 - 'title' => __( 'Requirements', 'learnpress' ),
801 - 'items' => $course->get_extra_info( 'requirements' ),
802 - ),
803 - array(
804 - 'title' => __( 'Features', 'learnpress' ),
805 - 'items' => $course->get_extra_info( 'key_features' ),
806 - ),
807 - array(
808 - 'title' => __( 'Target audiences', 'learnpress' ),
809 - 'items' => $course->get_extra_info( 'target_audiences' ),
810 - ),
811 - )
812 - );
813 -
814 - $is_checked = 0;
815 - foreach ( $boxes as $box ) {
816 -
817 - if ( ! isset( $box['items'] ) || ! $box['items'] ) {
818 - continue;
819 - }
820 -
821 - if ( ! $is_checked ) {
822 - $box['checked'] = true;
823 - $is_checked = true;
824 - }
825 -
826 - learn_press_get_template( 'single-course/extra-info', $box );
827 - }
828 - }
829 -
830 - /*public function metarials() {
831 - echo wp_kses_post( do_shortcode( '[learn_press_course_materials]' ) );
832 - }*/
833 -
834 - public function faqs() {
835 - $course = LP_Course::get_course( get_the_ID() );
836 - $faqs = $course->get_faqs();
837 - if ( ! $faqs ) {
838 - return;
839 - }
840 -
841 - foreach ( $faqs as $faq ) {
842 - learn_press_get_template( 'single-course/tabs/faqs', $faq );
843 - }
844 - }
845 -
846 - public function sidebar() {
847 - }
848 -
849 - public function course_featured_review() {
850 - $review_content = get_post_meta( $this->course->get_id(), '_lp_featured_review', true );
851 -
852 - if ( ! $review_content ) {
853 - return;
854 - }
855 -
856 - $user = learn_press_get_current_user();
857 -
858 - if ( ! $user ) {
859 - return;
860 - }
861 -
862 - if ( $user->has_enrolled_or_finished( $this->course->get_id() ) ) {
863 - return;
864 - }
865 -
866 - learn_press_get_template(
867 - 'single-course/featured-review',
868 - array(
869 - 'review_content' => $review_content,
870 - 'review_value' => 5,
871 - )
872 - );
873 - }
874 -
875 - public function has_sidebar() {
876 - $actions = array(
877 - 'learn-press/before-course-summary-sidebar',
878 - 'learn-press/course-summary-sidebar',
879 - 'learn-press/after-course-summary-sidebar',
880 - );
881 -
882 - foreach ( $actions as $action ) {
883 - if ( has_action( $action ) ) {
884 - return true;
885 - }
886 - }
887 -
888 - return false;
889 - }
890 -
891 - // button readmore in archive courses
892 - public function course_readmore() {
893 - ?>
894 - <div class="course-readmore">
895 - <a href="<?php the_permalink(); ?>"><?php echo esc_html__( 'View More', 'learnpress' ); ?></a>
896 - </div>
897 - <?php
898 - }
899 -
900 - public function course_item_comments() {
901 - global $post;
902 - $course = learn_press_get_course();
903 - if ( ! $course ) {
904 - return;
905 - }
906 -
907 - $item = LP_Global::course_item();
908 - if ( ! $item ) {
909 - return;
910 - }
911 -
912 - $user = learn_press_get_current_user();
913 - $user_can_view_course = $user->can_view_content_course( $course->get_id() );
914 - $user_can_view_item = $user->can_view_item( $item->get_id(), $user_can_view_course );
915 - if ( ! $user_can_view_item->flag ) {
916 - return;
917 - }
918 -
919 - if ( $item->setup_postdata() ) {
920 -
921 - if ( comments_open() || get_comments_number() ) {
922 - learn_press_get_template( 'single-course/item-comments' );
923 - }
924 - $item->reset_postdata();
925 - }
926 - }
927 -
928 -
929 - public function course_comment_template() {
930 - if ( comments_open() || get_comments_number() ) {
931 - add_filter( 'deprecated_file_trigger_error', '__return_false' );
932 - comments_template();
933 - remove_filter( 'deprecated_file_trigger_error', '__return_false' );
934 - }
935 - }
936 -
937 - /**
938 - * Show info time handle of user
939 - *
940 - * @throws Exception
941 - */
942 - public function user_time() {
943 - $user = learn_press_get_current_user();
944 -
945 - if ( ! $user ) {
946 - return;
947 - }
948 -
949 - if ( ! $user->has_enrolled_or_finished( $this->course->get_id() ) ) {
950 - return;
951 - }
952 -
953 - /**
954 - * @var LP_User_Item_Course
955 - */
956 - $user_course = $user->get_course_data( $this->course->get_id() );
957 -
958 - if ( ! $user_course ) {
959 - return;
960 - }
961 -
962 - $status = $user_course->get_status();
963 - $start_time = $user_course->get_start_time();
964 - $end_time = $user_course->get_end_time();
965 - $expiration_time = $user_course->get_expiration_time();
966 - $data = [
967 - 'status' => $status,
968 - 'start_time' => $start_time,
969 - 'end_time' => $end_time,
970 - 'expiration_time' => $expiration_time,
971 - ];
972 -
973 - learn_press_get_template(
974 - 'single-course/sidebar/user-time',
975 - compact( 'data' )
976 - );
977 - }
978 -
979 - /**
980 - * Animation placholder in user-progress file.
981 - * Content will show in class-rest-lazy-load-controller file.
982 - *
983 - * @return void
984 - * @throws Exception
985 - * @author Nhamdv.
986 - */
987 - public function user_progress() {
988 - if ( ! is_user_logged_in() ) {
989 - return;
990 - }
991 -
992 - $course = learn_press_get_course();
993 - $user = learn_press_get_current_user();
994 -
995 - if ( ! $course ) {
996 - return;
997 - }
998 -
999 - if ( ! $user->has_enrolled_or_finished( $course->get_id() ) ) {
1000 - return;
1001 - }
1002 -
1003 - if ( LP_LAZY_LOAD_ANIMATION ) {
1004 - echo '<div class="lp-course-progress-wrapper">';
1005 - lp_skeleton_animation_html();
1006 - echo '</div>';
1007 - } else {
1008 - $course_data = $user->get_course_data( $course->get_id() );
1009 - if ( ! $course_data ) {
1010 - return;
1011 - }
1012 -
1013 - $course_results = $course_data->calculate_course_results();
1014 -
1015 - learn_press_get_template(
1016 - 'single-course/sidebar/user-progress',
1017 - compact( 'user', 'course', 'course_data', 'course_results' )
1018 - );
1019 - }
1020 - }
1021 -
1022 - public function course_extra_boxes_position_control() {
1023 - $course = LP_Course::get_course( get_the_ID() );
1024 - $user = learn_press_get_current_user();
1025 - if ( ! $user || ! $course ) {
1026 - return;
1027 - }
1028 -
1029 - $enrolled = $user->has_enrolled_course( $course->get_id() );
1030 - if ( $enrolled ) {
1031 - remove_action(
1032 - 'learn-press/course-content-summary',
1033 - LearnPress::instance()->template( 'course' )->func( 'course_extra_boxes' ),
1034 - 40
1035 - );
1036 - } else {
1037 - remove_action(
1038 - 'learn-press/course-content-summary',
1039 - LearnPress::instance()->template( 'course' )->func( 'course_extra_boxes' ),
1040 - 70
1041 - );
1042 - }
1043 - }
1044 -
1045 - /**
1046 - * Template for case not any courses
1047 - *
1048 - * @author Nhamdv
1049 - * @since 4.1.2
1050 - */
1051 - public function no_courses_found() {
1052 - learn_press_get_template( 'global/no-courses-found' );
1053 - }
1054 -}
1055 -
1056 -return new LP_Template_Course();
1 +<?php
2 +
3 +use LearnPress\Helpers\Template;
4 +use LearnPress\Models\CourseModel;
5 +use LearnPress\Models\UserItems\UserCourseModel;
6 +use LearnPress\Models\UserModel;
7 +use LearnPress\TemplateHooks\Course\SingleCourseModernLayout;
8 +use LearnPress\TemplateHooks\Course\SingleCourseTemplate;
9 +use LearnPress\TemplateHooks\UserItem\UserCourseTemplate;
10 +
11 +/**
12 + * Class LP_Course_Template
13 + *
14 + * Groups templates related course and items
15 + *
16 + * @since 3.x.x
17 + */
18 +class LP_Template_Course extends LP_Abstract_Template {
19 + /**
20 + * @var LP_Course
21 + */
22 + public $course = null;
23 +
24 + /**
25 + * LP_Template_Course constructor.
26 + */
27 + public function __construct() {
28 + parent::__construct();
29 +
30 + add_action( 'the_post', array( $this, 'get_course' ) );
31 + }
32 +
33 + public function get_course() {
34 + // global $post;
35 +
36 + $this->course = learn_press_get_course();
37 + }
38 +
39 + public function course_sidebar_preview() {
40 + learn_press_get_template( 'single-course/sidebar/preview' );
41 + }
42 +
43 + public function course_buttons() {
44 + global $lp_user;
45 + $lp_user = learn_press_get_current_user();
46 + learn_press_get_template( 'single-course/buttons' );
47 + }
48 +
49 + public function course_graduation() {
50 + $user = learn_press_get_current_user();
51 + $course = learn_press_get_course();
52 +
53 + if ( ! $user || ! $course ) {
54 + return;
55 + }
56 +
57 + if ( ! $user->has_finished_course( $course->get_id() ) ) {
58 + return;
59 + }
60 +
61 + $graduation = $user->get_course_grade( $course->get_id() );
62 +
63 + learn_press_get_template( 'single-course/graduation', array( 'graduation' => $graduation ) );
64 + }
65 +
66 + /**
67 + * Show button retry course
68 + *
69 + * @throws Exception
70 + */
71 + public function button_retry( $course = null ) {
72 + _deprecated_function( __METHOD__, '4.3.2.4', 'UserCourseTemplate::html_btn_retake' );
73 + return;
74 +
75 + $user = learn_press_get_current_user();
76 + if ( empty( $course ) ) {
77 + $course = learn_press_get_course();
78 + }
79 +
80 + if ( ! $user || ! $course ) {
81 + return;
82 + }
83 +
84 + $can_retake_times = $user->can_retry_course( $course->get_id() );
85 +
86 + // Course has no items
87 + if ( empty( $course->count_items() ) ) {
88 + return;
89 + }
90 +
91 + if ( $can_retake_times ) {
92 + learn_press_get_template(
93 + 'single-course/buttons/retry',
94 + array( 'can_retake_times' => $can_retake_times )
95 + );
96 + }
97 + }
98 +
99 + public function course_media_preview() {
100 + $course = learn_press_get_course();
101 +
102 + echo wp_kses_post( $course->get_image() );
103 + }
104 +
105 + /**
106 + * @param LP_Quiz $item
107 + */
108 + public function quiz_meta_questions( $item ) {
109 + $count = $item->count_questions();
110 + printf(
111 + '<span class="item-meta count-questions">%s</span>',
112 + sprintf( _n( '%1$d question', '%1$d questions', $count, 'learnpress' ), $count )
113 + );
114 + }
115 +
116 + /**
117 + * @param LP_Quiz|LP_Lesson $item
118 + */
119 + public function item_meta_duration( $item ) {
120 + $duration = learn_press_get_post_translated_duration( $item->get_id(), false );
121 +
122 + if ( $duration ) {
123 + echo '<span class="item-meta duration">' . $duration . '</span>';
124 + }
125 + }
126 +
127 + /**
128 + * @var LP_Course_Item $item
129 + */
130 + public function quiz_meta_final( $item ) {
131 + $course = $item->get_course();
132 +
133 + if ( ! $course || ! $course->is_final_quiz( $item->get_id() )
134 + || $course->get_evaluation_type() != 'evaluate_final_quiz' ) {
135 + return;
136 + }
137 +
138 + echo '<span class="item-meta final-quiz">' . esc_html__( 'Final', 'learnpress' ) . '</span>';
139 + }
140 +
141 + public function course_button() {
142 + echo '[COURSE BUTTON]';
143 + }
144 +
145 + public function course_title() {
146 + echo '[COURSE TITLE]';
147 + }
148 +
149 + public function courses_top_bar() {
150 + learn_press_get_template( 'courses-top-bar' );
151 + }
152 +
153 + /**
154 + * Display price or free of course, not button, it is label.
155 + *
156 + * @return void
157 + * @since 4.0.0
158 + * @version 1.0.3
159 + */
160 + public function course_pricing() {
161 + $course = learn_press_get_course();
162 + $user = learn_press_get_current_user();
163 +
164 + $courseModel = CourseModel::find( $course->get_id(), true );
165 + $can_purchase = $courseModel->can_purchase( UserModel::find( $user->get_id(), true ) );
166 + $userCourseModel = UserCourseModel::find( $user->get_id(), $course->get_id(), true );
167 + if ( get_current_user_id() ) {
168 + if ( $userCourseModel ) {
169 + if ( $userCourseModel->has_enrolled() ) {
170 + return;
171 + } elseif ( $can_purchase instanceof WP_Error ) {
172 + return;
173 + }
174 + }
175 + }
176 +
177 + $price_html = $course->get_course_price_html();
178 + learn_press_get_template( 'single-course/price', compact( 'course', 'user', 'price_html' ) );
179 + }
180 +
181 + /**
182 + * Template purchase course button
183 + *
184 + * @editor tungnx
185 + * @modify 4.1.3.1
186 + * @throws Exception
187 + * @version 4.0.2
188 + */
189 + public function course_purchase_button( $course = null ) {
190 + _deprecated_function( __METHOD__, '4.3.2', 'SingleCourseTemplate::html_btn_purchase_course' );
191 + return;
192 +
193 + $singleCourseTemplate = SingleCourseTemplate::instance();
194 + $course = CourseModel::find( get_the_ID(), true );
195 + $user = UserModel::find( get_current_user_id(), true );
196 + echo $singleCourseTemplate->html_btn_purchase_course( $course, $user );
197 + }
198 +
199 + /**
200 + * Show button enroll course
201 + *
202 + * @editor tungnx
203 + * @modify 4.1.3.1
204 + * @throws Exception
205 + * @version 4.0.3
206 + */
207 + public function course_enroll_button( $course = null ) {
208 + _deprecated_function( __METHOD__, '4.3.2.4', 'SingleCourseTemplate::html_btn_enroll_course' );
209 + return;
210 +
211 + $singleCourseTemplate = SingleCourseTemplate::instance();
212 + $course = CourseModel::find( get_the_ID(), true );
213 + $user = UserModel::find( get_current_user_id(), true );
214 + echo $singleCourseTemplate->html_btn_enroll_course( $course, $user );
215 + return;
216 +
217 + $can_show = true;
218 + $user = learn_press_get_current_user();
219 + if ( empty( $course ) ) {
220 + $course = learn_press_get_course();
221 + }
222 + $error_code = '';
223 +
224 + try {
225 + if ( ! $course || ! $user ) {
226 + throw new Exception( 'User or Course is not exists' );
227 + }
228 +
229 + // User can not enroll course.
230 + $can_enroll_course = $user->can_enroll_course( $course->get_id(), false );
231 + if ( ! $can_enroll_course->check ) {
232 + $error_code = $can_enroll_course->code;
233 + throw new Exception( $can_enroll_course->message );
234 + }
235 +
236 + if ( $user->has_finished_course( $course->get_id() ) ) {
237 + $error_code = 'course_is_finished';
238 + throw new Exception( __( 'Course is finished', 'learnpress' ) );
239 + }
240 + } catch ( Throwable $e ) {
241 + if ( ! in_array( $error_code, [ 'course_is_enrolled', 'course_can_retry' ] ) ) {
242 + if ( $course && $course->is_free() ) {
243 + Template::print_message( $e->getMessage(), 'warning' );
244 + }
245 + }
246 + $can_show = false;
247 + }
248 +
249 + $can_show = apply_filters( 'learnpress/course/template/button-enroll/can-show', $can_show, $user, $course );
250 + if ( ! $can_show ) {
251 + return;
252 + }
253 +
254 + $args = array(
255 + 'user' => $user,
256 + 'course' => $course,
257 + );
258 +
259 + learn_press_get_template( 'single-course/buttons/enroll.php', $args );
260 + }
261 +
262 + public function course_extra_requirements( $course_id ) {
263 + $course = LP_Course::get_course( $course_id );
264 + if ( ! $course ) {
265 + return;
266 + }
267 +
268 + $requirements = apply_filters(
269 + 'learn-press/course-extra-requirements',
270 + $course->get_extra_info( 'requirements' ),
271 + $course_id
272 + );
273 +
274 + if ( ! $requirements ) {
275 + return;
276 + }
277 +
278 + learn_press_get_template(
279 + 'single-course/sidebar/course-extra',
280 + array(
281 + 'type' => 'requirements',
282 + 'title' => esc_html__( 'Requirements', 'learnpress' ),
283 + 'content' => $requirements,
284 + )
285 + );
286 + }
287 +
288 + public function course_extra_key_features( $course_id ) {
289 + $course = LP_Course::get_course( $course_id );
290 + if ( ! $course ) {
291 + return;
292 + }
293 +
294 + $key_features = apply_filters(
295 + 'learn-press/course-extra-key-features',
296 + $course->get_extra_info( 'key_features' ),
297 + $course_id
298 + );
299 +
300 + if ( ! $key_features ) {
301 + return;
302 + }
303 +
304 + learn_press_get_template(
305 + 'single-course/sidebar/course-extra',
306 + array(
307 + 'type' => 'key-features',
308 + 'title' => esc_html__( 'Key features', 'learnpress' ),
309 + 'content' => $key_features,
310 + )
311 + );
312 + }
313 +
314 + public function course_extra_target_audiences( $course_id ) {
315 + $course = LP_Course::get_course( $course_id );
316 + if ( ! $course ) {
317 + return;
318 + }
319 +
320 + $target_audiences = apply_filters(
321 + 'learn-press/course-extra-target-audiences',
322 + $course->get_extra_info( 'target_audiences' ),
323 + $course_id
324 + );
325 +
326 + if ( ! $target_audiences ) {
327 + return;
328 + }
329 +
330 + learn_press_get_template(
331 + 'single-course/sidebar/course-extra',
332 + array(
333 + 'type' => 'target-audiences',
334 + 'title' => esc_html__( 'Target audiences', 'learnpress' ),
335 + 'content' => $target_audiences,
336 + )
337 + );
338 + }
339 +
340 + /**
341 + * Show template "continue" button con single course
342 + *
343 + * @throws Exception
344 + * @modify 4.1.3.1
345 + * @version 4.0.4
346 + * @since 4.0.0
347 + */
348 + public static function course_continue_button( $args = [] ) {
349 + _deprecated_function( __METHOD__, '4.3.2.4', 'UserCourseTemplate::html_btn_continue' );
350 + return;
351 +
352 + $course_id_param = $args['course-id'] ?? 0;
353 + $course_id = ! empty( $course_id_param ) ? $course_id_param : get_the_ID();
354 + $courseModel = CourseModel::find( $course_id, true );
355 + $user_id = get_current_user_id();
356 +
357 + try {
358 + if ( ! $user_id || ! $courseModel ) {
359 + throw new Exception( 'User or Course not exists!' );
360 + }
361 +
362 + $userCourseModel = UserCourseModel::find( $user_id, $courseModel->get_id(), true );
363 + if ( ! $userCourseModel || ! $userCourseModel->has_enrolled() ) {
364 + throw new Exception( 'User not enrolled course' );
365 + }
366 +
367 + if ( $userCourseModel->has_finished() ) {
368 + throw new Exception( 'User has finished course' );
369 + }
370 +
371 + // Course has no items
372 + if ( empty( $courseModel->get_total_items() ) ) {
373 + throw new Exception( 'Course no any item' );
374 + }
375 +
376 + // Do not display continue button if course is block duration
377 + if ( $userCourseModel->timestamp_remaining_duration() === 0 ) {
378 + throw new Exception( 'Course is blocked' );
379 + }
380 +
381 + $section = [
382 + 'start' => '<div>',
383 + 'link' => UserCourseTemplate::instance()->html_btn_continue( $userCourseModel ),
384 + 'end' => '</div>',
385 + ];
386 +
387 + echo Template::combine_components( $section );
388 + } catch ( Throwable $e ) {
389 +
390 + }
391 + }
392 +
393 + public function course_finish_button( $course = null ) {
394 + _deprecated_function( __METHOD__, '4.3.2.4', 'UserCourseTemplate::html_btn_finish' );
395 + return;
396 +
397 + $user = learn_press_get_current_user();
398 + if ( empty( $course ) ) {
399 + $course = learn_press_get_course();
400 + }
401 +
402 + if ( ! $course ) {
403 + return;
404 + }
405 +
406 + // Course has no items
407 + if ( empty( $course->count_items() ) ) {
408 + return;
409 + }
410 +
411 + $check = $user->can_show_finish_course_btn( $course );
412 +
413 + if ( 'success' !== $check['status'] ) {
414 + return;
415 + }
416 +
417 + learn_press_get_template(
418 + 'single-course/buttons/finish.php',
419 + array(
420 + 'course' => $course,
421 + 'user' => $user,
422 + )
423 + );
424 + }
425 +
426 + /**
427 + * Button course external link
428 + *
429 + * @throws Exception
430 + * @editor tungnx
431 + * @modify 4.1.3
432 + */
433 + public function course_external_button( $course = null ) {
434 + _deprecated_function( __METHOD__, '4.3.2.4', 'SingleCourseTemplate::html_btn_external' );
435 + return;
436 +
437 + if ( empty( $course ) ) {
438 + $course = learn_press_get_course();
439 + }
440 +
441 + $user = learn_press_get_current_user();
442 +
443 + if ( ! $course ) {
444 + return;
445 + }
446 +
447 + $link = $course->get_external_link();
448 + if ( empty( $link ) || $user->has_purchased_course( $course->get_id() ) ) {
449 + return;
450 + }
451 +
452 + $user = learn_press_get_current_user();
453 +
454 + if ( $user && ! $user->has_enrolled_or_finished( $course->get_id() ) ) {
455 + // Remove all another buttons
456 + // learn_press_remove_course_buttons();
457 + learn_press_get_template( 'single-course/buttons/external-link.php' );
458 +
459 + // Add back other buttons for other courses
460 + add_action( 'learn-press/after-course-buttons', 'learn_press_add_course_buttons' );
461 + }
462 + }
463 +
464 + public function popup_header() {
465 + $user = learn_press_get_current_user();
466 + $course = learn_press_get_course();
467 +
468 + if ( ! $user || ! $course ) {
469 + return;
470 + }
471 +
472 + $percentage = 0;
473 + $total_items = 0;
474 + $completed_items = 0;
475 + $course_data = $user->get_course_data( $course->get_id() );
476 +
477 + if ( $course_data && ! empty( $course_data->get_user_id() ) && ! $course->is_no_required_enroll() ) {
478 + $course_results = $course_data->get_result();
479 + $completed_items = $course_results['completed_items'];
480 + $total_items = $course_results['count_items'];
481 + $percentage = $course_results['count_items'] ? absint( $course_results['completed_items'] / $course_results['count_items'] * 100 ) : 0;
482 + }
483 +
484 + learn_press_get_template( 'single-course/content-item/popup-header', compact( 'user', 'course', 'total_items', 'completed_items', 'percentage' ) );
485 + }
486 +
487 + public function popup_sidebar() {
488 + learn_press_get_template( 'single-course/content-item/popup-sidebar' );
489 + }
490 +
491 + /**
492 + * Get single item's course
493 + */
494 + public function popup_content() {
495 + learn_press_get_template( 'single-course/content-item/popup-content' );
496 + }
497 +
498 + public function popup_footer() {
499 + learn_press_get_template( 'single-course/content-item/popup-footer' );
500 + }
501 +
502 + public function popup_footer_nav() {
503 + $course = learn_press_get_course();
504 + if ( ! $course ) {
505 + return;
506 + }
507 +
508 + $next_item = false;
509 + $prev_item = false;
510 +
511 + $next_id = $course->get_next_item();
512 + $prev_id = $course->get_prev_item();
513 +
514 + if ( $next_id ) {
515 + $next_item = $course->get_item( $next_id );
516 + if ( $next_item instanceof LP_Course_Item ) {
517 + $next_item->set_course( $course->get_id() );
518 + }
519 + }
520 +
521 + if ( $prev_id ) {
522 + $prev_item = $course->get_item( $prev_id );
523 + if ( $prev_item instanceof LP_Course_Item ) {
524 + $prev_item->set_course( $course->get_id() );
525 + }
526 + }
527 +
528 + if ( ! $prev_item && ! $next_item ) {
529 + return;
530 + }
531 +
532 + learn_press_get_template(
533 + 'single-course/content-item/nav.php',
534 + array(
535 + 'next_item' => $next_item,
536 + 'prev_item' => $prev_item,
537 + )
538 + );
539 + }
540 +
541 + /**
542 + * Display course curriculum.
543 + *
544 + * @since 4.1.6
545 + * @since 4.2.5.5 remove code load old template user for course curriculum load page instead of via AJAX.
546 + * @version 1.0.2
547 + * @depreacted 4.2.8.7.1
548 + */
549 + public function course_curriculum() {
550 + /**
551 + * @var CourseModel $lpCourseModel
552 + */
553 + global $lpCourseModel;
554 + $courseModel = CourseModel::find( get_the_ID(), true );
555 + if ( $lpCourseModel instanceof CourseModel ) {
556 + $courseModel = $lpCourseModel;
557 + }
558 +
559 + $course_item = LP_Global::course_item();
560 + $userModel = UserModel::find( get_current_user_id(), true );
561 +
562 + $singleCourseTemplate = SingleCourseTemplate::instance();
563 + echo $singleCourseTemplate->html_curriculum( $courseModel, $userModel );
564 + }
565 +
566 + /**
567 + * Display course curriculum.
568 + *
569 + * @since 4.1.6
570 + * @since 4.2.5.5 remove code load old template user for course curriculum load page instead of via AJAX.
571 + * @version 1.0.2
572 + */
573 + public function course_curriculum_bk() {
574 + /**
575 + * @var CourseModel $lpCourseModel
576 + */
577 + global $lpCourseModel;
578 + $course_item = LP_Global::course_item();
579 +
580 + if ( $course_item ) { // Check if current item is viewable
581 + $course_id = 0;
582 + if ( $lpCourseModel ) {
583 + $course_id = $lpCourseModel->get_id();
584 + }
585 +
586 + $item_id = (int) $course_item->get_id();
587 + $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id, $course_id );
588 + }
589 + ?>
590 + <div class="learnpress-course-curriculum" data-section="<?php echo esc_attr( $section_id ?? '' ); ?>"
591 + data-id="<?php echo esc_attr( $item_id ?? '' ); ?>">
592 + <?php lp_skeleton_animation_html( 10 ); ?>
593 + </div>
594 + <?php
595 + }
596 +
597 + /**
598 + * Get template content item's course
599 + */
600 + public function course_content_item() {
601 + learn_press_get_template( 'single-course/content-item' );
602 + }
603 +
604 + public function courses_loop_item_meta() {
605 + learn_press_get_template( 'loop/course/meta' );
606 + }
607 +
608 + public function courses_loop_item_info_begin() {
609 + learn_press_get_template( 'loop/course/info-begin' );
610 + }
611 +
612 + public function courses_loop_item_info_end() {
613 + learn_press_get_template( 'loop/course/info-end' );
614 + }
615 +
616 + public function courses_loop_item_price() {
617 + $course = learn_press_get_course();
618 + if ( ! $course ) {
619 + return;
620 + }
621 +
622 + $price_html = $course->get_course_price_html();
623 + learn_press_get_template( 'loop/course/price', compact( 'course', 'price_html' ) );
624 + }
625 +
626 + public function begin_courses_loop() {
627 + learn_press_get_template( 'loop/course/loop-begin.php' );
628 + }
629 +
630 + public function end_courses_loop() {
631 + learn_press_get_template( 'loop/course/loop-end.php' );
632 + }
633 +
634 + public function course_item_content() {
635 + $course = learn_press_get_course();
636 + if ( ! $course ) {
637 + return;
638 + }
639 +
640 + $item = LP_Global::course_item();
641 +
642 + /**
643 + * Fix only for WPBakery load style inline
644 + * custom CSS is provided, load inline style.
645 + *
646 + * @editor tuanta
647 + * @since 3.2.8.1
648 + */
649 + $shortcodes_custom_css = get_post_meta( $item->get_id(), '_wpb_shortcodes_custom_css', true );
650 +
651 + if ( ! empty( $shortcodes_custom_css ) ) {
652 + $shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
653 + echo '<style data-type="vc_shortcodes-custom-css">';
654 + echo wp_kses_post( $shortcodes_custom_css );
655 + echo '</style>';
656 + }
657 + // End
658 +
659 + $timestamp_remaining = $course->timestamp_remaining_duration();
660 + if ( $timestamp_remaining > 0 ) {
661 + echo '<input type="hidden" name="lp-course-timestamp-remaining" value="' . esc_attr( $timestamp_remaining ) . '">';
662 + }
663 + // End
664 +
665 + $item_template_name = learn_press_locate_template( 'single-course/content-item-' . $item->get_item_type() . '.php' );
666 +
667 + if ( file_exists( $item_template_name ) ) {
668 + learn_press_get_template( 'single-course/content-item-' . $item->get_item_type() . '.php' );
669 + } else {
670 + echo esc_html( sprintf( 'File %s not exists', $item_template_name ) );
671 + }
672 + }
673 +
674 + public function item_lesson_title() {
675 + $item = LP_Global::course_item();
676 + $format = $item->get_format();
677 + $format_template = learn_press_locate_template( "content-lesson/{$format}/title.php" );
678 +
679 + if ( 'standard' !== $format && file_exists( $format_template ) ) {
680 + include $format_template;
681 +
682 + return;
683 + }
684 + learn_press_get_template( 'content-lesson/title.php', array( 'lesson' => $item ) );
685 + }
686 +
687 + public function item_lesson_content() {
688 + $item = LP_Global::course_item();
689 + $format = $item->get_format();
690 + $format_template = learn_press_locate_template( "content-lesson/{$format}/content.php" );
691 +
692 + if ( 'standard' !== $format && file_exists( $format_template ) ) {
693 + include $format_template;
694 +
695 + return;
696 + }
697 + do_action( 'learn-press/lesson-start', $item );
698 +
699 + Template::instance()->get_frontend_template( 'content-lesson/content.php', array( 'lesson' => $item ) );
700 + }
701 +
702 + /**
703 + * Get template button complete lesson
704 + */
705 + public function item_lesson_complete_button() {
706 + $user = learn_press_get_current_user();
707 + $course = learn_press_get_course();
708 + if ( ! $course ) {
709 + return;
710 + }
711 +
712 + try {
713 + $item = LP_Global::course_item();
714 + if ( ! $user || ! $user->is_course_in_progress( $course->get_id() ) ) {
715 + return;
716 + }
717 +
718 + // The complete button is not displayed when the course is locked --hungkv--
719 + if ( $user->can_view_content_course( $course->get_id() )->key === LP_BLOCK_COURSE_DURATION_EXPIRE ) {
720 + return;
721 + }
722 +
723 + learn_press_get_template(
724 + 'content-lesson/button-complete.php',
725 + array(
726 + 'user' => $user,
727 + 'course' => $course,
728 + 'item' => $item,
729 + )
730 + );
731 + } catch ( Throwable $e ) {
732 + error_log( $e->getMessage() );
733 + }
734 + }
735 +
736 + public function item_lesson_material() {
737 + try {
738 + do_action( 'learn-press/course-material/layout', [] );
739 + } catch ( Throwable $e ) {
740 + error_log( $e->getMessage() );
741 + }
742 + }
743 +
744 + /**
745 + * Template show count items
746 + *
747 + * @since 4.0.0
748 + * @version 1.0.2
749 + * @editor tungnx
750 + */
751 + public function count_object() {
752 + $course = CourseModel::find( get_the_ID(), true );
753 + if ( ! $course ) {
754 + return;
755 + }
756 +
757 + $lessons = $course->count_items( LP_LESSON_CPT );
758 + $quizzes = $course->count_items( LP_QUIZ_CPT );
759 + $students = $course->count_students();
760 +
761 + $counts = apply_filters(
762 + 'learnpress/course/count/items',
763 + array(
764 + 'lesson' => sprintf(
765 + '<span class="meta-number">' . _n( '%d lesson', '%d lessons', $lessons, 'learnpress' ) . '</span>',
766 + $lessons
767 + ),
768 + 'quiz' => sprintf(
769 + '<span class="meta-number">' . _n( '%d quiz', '%d quizzes', $quizzes, 'learnpress' ) . '</span>',
770 + $quizzes
771 + ),
772 + 'student' => sprintf(
773 + '<span class="meta-number">' . _n( '%d student', '%d students', $students, 'learnpress' ) . '</span>',
774 + $students
775 + ),
776 + ),
777 + array( $lessons, $quizzes, $students )
778 + );
779 +
780 + foreach ( $counts as $object => $count ) {
781 + learn_press_get_template(
782 + 'single-course/meta/count',
783 + array(
784 + 'count' => $count,
785 + 'object' => $object,
786 + )
787 + );
788 + }
789 + }
790 +
791 + public function course_extra_boxes() {
792 + $course = LP_Course::get_course( get_the_ID() );
793 + if ( ! $course ) {
794 + return;
795 + }
796 +
797 + $boxes = apply_filters(
798 + 'learn-press/course-extra-boxes-data',
799 + array(
800 + array(
801 + 'title' => __( 'Requirements', 'learnpress' ),
802 + 'items' => $course->get_extra_info( 'requirements' ),
803 + ),
804 + array(
805 + 'title' => __( 'Features', 'learnpress' ),
806 + 'items' => $course->get_extra_info( 'key_features' ),
807 + ),
808 + array(
809 + 'title' => __( 'Target audiences', 'learnpress' ),
810 + 'items' => $course->get_extra_info( 'target_audiences' ),
811 + ),
812 + )
813 + );
814 +
815 + $is_checked = 0;
816 + foreach ( $boxes as $box ) {
817 +
818 + if ( ! isset( $box['items'] ) || ! $box['items'] ) {
819 + continue;
820 + }
821 +
822 + if ( ! $is_checked ) {
823 + $box['checked'] = true;
824 + $is_checked = true;
825 + }
826 +
827 + learn_press_get_template( 'single-course/extra-info', $box );
828 + }
829 + }
830 +
831 + /*public function metarials() {
832 + echo wp_kses_post( do_shortcode( '[learn_press_course_materials]' ) );
833 + }*/
834 +
835 + public function faqs() {
836 + $course = LP_Course::get_course( get_the_ID() );
837 + $faqs = $course->get_faqs();
838 + if ( ! $faqs ) {
839 + return;
840 + }
841 +
842 + foreach ( $faqs as $faq ) {
843 + learn_press_get_template( 'single-course/tabs/faqs', $faq );
844 + }
845 + }
846 +
847 + public function sidebar() {
848 + }
849 +
850 + public function course_featured_review() {
851 + $review_content = get_post_meta( $this->course->get_id(), '_lp_featured_review', true );
852 +
853 + if ( ! $review_content ) {
854 + return;
855 + }
856 +
857 + $user = learn_press_get_current_user();
858 +
859 + if ( ! $user ) {
860 + return;
861 + }
862 +
863 + if ( $user->has_enrolled_or_finished( $this->course->get_id() ) ) {
864 + return;
865 + }
866 +
867 + learn_press_get_template(
868 + 'single-course/featured-review',
869 + array(
870 + 'review_content' => $review_content,
871 + 'review_value' => 5,
872 + )
873 + );
874 + }
875 +
876 + public function has_sidebar() {
877 + $actions = array(
878 + 'learn-press/before-course-summary-sidebar',
879 + 'learn-press/course-summary-sidebar',
880 + 'learn-press/after-course-summary-sidebar',
881 + );
882 +
883 + foreach ( $actions as $action ) {
884 + if ( has_action( $action ) ) {
885 + return true;
886 + }
887 + }
888 +
889 + return false;
890 + }
891 +
892 + // button readmore in archive courses
893 + public function course_readmore() {
894 + ?>
895 + <div class="course-readmore">
896 + <a href="<?php the_permalink(); ?>"><?php echo esc_html__( 'View More', 'learnpress' ); ?></a>
897 + </div>
898 + <?php
899 + }
900 +
901 + public function course_item_comments() {
902 + global $post;
903 + $course = learn_press_get_course();
904 + if ( ! $course ) {
905 + return;
906 + }
907 +
908 + $item = LP_Global::course_item();
909 + if ( ! $item ) {
910 + return;
911 + }
912 +
913 + $user = learn_press_get_current_user();
914 + $user_can_view_course = $user->can_view_content_course( $course->get_id() );
915 + $user_can_view_item = $user->can_view_item( $item->get_id(), $user_can_view_course );
916 + if ( ! $user_can_view_item->flag ) {
917 + return;
918 + }
919 +
920 + if ( $item->setup_postdata() ) {
921 +
922 + if ( comments_open() || get_comments_number() ) {
923 + learn_press_get_template( 'single-course/item-comments' );
924 + }
925 + $item->reset_postdata();
926 + }
927 + }
928 +
929 +
930 + public function course_comment_template() {
931 + if ( comments_open() || get_comments_number() ) {
932 + add_filter( 'deprecated_file_trigger_error', '__return_false' );
933 + comments_template();
934 + remove_filter( 'deprecated_file_trigger_error', '__return_false' );
935 + }
936 + }
937 +
938 + /**
939 + * Show info time handle of user
940 + *
941 + * @throws Exception
942 + * @deprecated 4.4.0
943 + */
944 + public function user_time() {
945 + _deprecated_function( __METHOD__, '4.4.0' );
946 + return;
947 + $user = learn_press_get_current_user();
948 +
949 + if ( ! $user ) {
950 + return;
951 + }
952 +
953 + if ( ! $user->has_enrolled_or_finished( $this->course->get_id() ) ) {
954 + return;
955 + }
956 +
957 + /**
958 + * @var LP_User_Item_Course
959 + */
960 + $user_course = $user->get_course_data( $this->course->get_id() );
961 +
962 + if ( ! $user_course ) {
963 + return;
964 + }
965 +
966 + $status = $user_course->get_status();
967 + $start_time = $user_course->get_start_time();
968 + $end_time = $user_course->get_end_time();
969 + $expiration_time = $user_course->get_expiration_time();
970 + $data = [
971 + 'status' => $status,
972 + 'start_time' => $start_time,
973 + 'end_time' => $end_time,
974 + 'expiration_time' => $expiration_time,
975 + ];
976 +
977 + learn_press_get_template(
978 + 'single-course/sidebar/user-time',
979 + compact( 'data' )
980 + );
981 + }
982 +
983 + /**
984 + * Animation placholder in user-progress file.
985 + * Content will show in class-rest-lazy-load-controller file.
986 + *
987 + * @return void
988 + * @throws Exception
989 + * @author Nhamdv.
990 + */
991 + public function user_progress() {
992 + $courseModel = CourseModel::find( get_the_ID(), true );
993 + if ( ! $courseModel ) {
994 + return;
995 + }
996 +
997 + $userModel = UserModel::find( get_current_user_id(), true );
998 + echo SingleCourseModernLayout::instance()->html_info_learning( $courseModel, $userModel );
999 +
1000 + /*if ( LP_LAZY_LOAD_ANIMATION ) {
1001 + echo '<div class="lp-course-progress-wrapper">';
1002 + lp_skeleton_animation_html();
1003 + echo '</div>';
1004 + } else {
1005 + $course_data = $user->get_course_data( $course->get_id() );
1006 + if ( ! $course_data ) {
1007 + return;
1008 + }
1009 +
1010 + $course_results = $course_data->calculate_course_results();
1011 +
1012 + learn_press_get_template(
1013 + 'single-course/sidebar/user-progress',
1014 + compact( 'user', 'course', 'course_data', 'course_results' )
1015 + );
1016 + }*/
1017 + }
1018 +
1019 + public function course_extra_boxes_position_control() {
1020 + $course = LP_Course::get_course( get_the_ID() );
1021 + $user = learn_press_get_current_user();
1022 + if ( ! $user || ! $course ) {
1023 + return;
1024 + }
1025 +
1026 + $enrolled = $user->has_enrolled_course( $course->get_id() );
1027 + if ( $enrolled ) {
1028 + remove_action(
1029 + 'learn-press/course-content-summary',
1030 + LearnPress::instance()->template( 'course' )->func( 'course_extra_boxes' ),
1031 + 40
1032 + );
1033 + } else {
1034 + remove_action(
1035 + 'learn-press/course-content-summary',
1036 + LearnPress::instance()->template( 'course' )->func( 'course_extra_boxes' ),
1037 + 70
1038 + );
1039 + }
1040 + }
1041 +
1042 + /**
1043 + * Template for case not any courses
1044 + *
1045 + * @author Nhamdv
1046 + * @since 4.1.2
1047 + */
1048 + public function no_courses_found() {
1049 + learn_press_get_template( 'global/no-courses-found' );
1050 + }
1051 +}
1052 +
1053 +return new LP_Template_Course();