PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/TemplateHooks/Course/SingleCourseModernLayout.php +607 -574 4.3.9.14.4.8 View file →
@@ -1,574 +1,607 @@
1 -<?php
2 -/**
3 - * Template hooks Single Course Online.
4 - *
5 - * @since 4.2.7
6 - * @version 1.0.0
7 - */
8 -
9 -namespace LearnPress\TemplateHooks\Course;
10 -
11 -use LearnPress\Helpers\Singleton;
12 -use LearnPress\Helpers\Template;
13 -use LearnPress\Models\CourseModel;
14 -use LearnPress\Models\UserItems\UserCourseModel;
15 -use LearnPress\Models\UserItems\UserItemModel;
16 -use LearnPress\TemplateHooks\UserItem\UserCourseTemplate;
17 -use LearnPress\Models\UserModel;
18 -use LearnPress\TemplateHooks\Instructor\SingleInstructorTemplate;
19 -
20 -class SingleCourseModernLayout {
21 - use Singleton;
22 -
23 - /**
24 - * @var SingleCourseTemplate
25 - */
26 - public $singleCourseTemplate;
27 -
28 - public function init() {
29 - $this->singleCourseTemplate = SingleCourseTemplate::instance();
30 -
31 - add_action(
32 - 'learn-press/single-course/layout',
33 - [ $this, 'course_model_layout' ]
34 - );
35 - }
36 -
37 - /**
38 - * Single course layout model
39 - *
40 - * @param $course
41 - *
42 - * @return void
43 - */
44 - public function course_model_layout( $course ) {
45 - if ( ! $course instanceof CourseModel ) {
46 - return;
47 - }
48 -
49 - $user = UserModel::find( get_current_user_id(), true );
50 -
51 - // Related courses
52 - ob_start();
53 - do_action( 'learn-press/single-course/courses-related/layout', $course, 4 );
54 - $html_courses_related = ob_get_clean();
55 -
56 - // Global message
57 - ob_start();
58 - learn_press_show_message();
59 - $global_message = ob_get_clean();
60 -
61 - $sections = apply_filters(
62 - 'learn-press/single-course/modern/sections',
63 - [
64 - 'wrapper' => '<div class="lp-single-course">',
65 - 'section_header' => $this->header_sections( $course, $user ),
66 - 'wrapper_container' => '<div class="lp-content-area">',
67 - 'wrapper_main' => '<div class="lp-single-course-main">',
68 - 'global_message' => $global_message,
69 - 'section_left' => $this->section_left( $course, $user ),
70 - 'section_right' => $this->section_right( $course, $user ),
71 - 'wrapper_main_end' => '</div>',
72 - 'related_courses' => $html_courses_related,
73 - 'wrapper_container_end' => '</div>',
74 - 'wrapper_end' => '</div>',
75 - ]
76 - );
77 -
78 - echo Template::combine_components( $sections );
79 - }
80 -
81 - /**
82 - * HTML header section
83 - *
84 - * @param $course
85 - * @param $user
86 - *
87 - * @return string
88 - */
89 - public function header_sections( $course, $user ): string {
90 - $html_categories = $this->singleCourseTemplate->html_categories( $course );
91 - if ( ! empty( $html_categories ) ) {
92 - $html_categories = sprintf(
93 - '<div>%s %s</div>',
94 - sprintf( '<label>%s</label>', __( 'in', 'learnpress' ) ),
95 - $html_categories
96 - );
97 - }
98 -
99 - $section_info_one = apply_filters(
100 - 'learn-press/single-course/modern/header/info-meta',
101 - [
102 - 'wrapper' => '<div class="lp-single-course-info-one">',
103 - 'author' => '',
104 - 'last_update' => sprintf(
105 - '<div class="item-meta">%s: %s</div>',
106 - esc_html__( 'Last updated', 'learnpress' ),
107 - esc_attr( get_post_modified_time( get_option( 'date_format' ), true ) )
108 - ),
109 - 'wrapper_end' => '</div>',
110 - ],
111 - $course,
112 - $user
113 - );
114 - if ( ! has_filter( 'learn-press/single-course/modern/header/info-meta' ) ) {
115 - // Do not use this hook, this hook only for handle hook without update from Addon, when handle on Addon, will remove this hook
116 - $section_info_one = apply_filters(
117 - 'learn-press/single-course/offline/info-bar',
118 - $section_info_one,
119 - $course,
120 - $user
121 - );
122 - }
123 -
124 - $html_instructor = sprintf(
125 - '<div>%s %s</div>',
126 - sprintf( '<label>%s</label>', __( 'by', 'learnpress' ) ),
127 - $this->singleCourseTemplate->html_instructor( $course )
128 - );
129 -
130 - $header_sections = apply_filters(
131 - 'learn-press/single-course/modern/header/sections',
132 - [
133 - 'wrapper_header' => '<div class="lp-single-course__header">',
134 - 'wrapper_container' => '<div class="lp-single-course__header__inner">',
135 - 'breadcrumb' => Template::html_breadcrumb(),
136 - 'title' => $this->singleCourseTemplate->html_title( $course, 'h1' ),
137 - 'wrapper_instructor_cate' => '<div class="course-instructor-category">',
138 - 'instructor' => $html_instructor,
139 - 'category' => $html_categories,
140 - 'wrapper_instructor_cate_end' => '</div>',
141 - 'info_one' => Template::combine_components( $section_info_one ),
142 - 'wrapper_container_end' => '</div>',
143 - 'wrapper_header_end' => '</div>',
144 - ],
145 - $course,
146 - $user
147 - );
148 -
149 - return Template::combine_components( $header_sections );
150 - }
151 -
152 - /**
153 - * HTML left section
154 - *
155 - * @param $course
156 - * @param $user
157 - *
158 - * @return string
159 - */
160 - public function section_left( $course, $user ): string {
161 - $section = apply_filters(
162 - 'learn-press/single-course/modern/section_left',
163 - [
164 - 'wrapper' => '<div class="lp-single-course-main__left">',
165 - 'description' => $this->singleCourseTemplate->html_description( $course ),
166 - 'features' => $this->singleCourseTemplate->html_features( $course ),
167 - 'target' => $this->singleCourseTemplate->html_target( $course ),
168 - 'requirements' => $this->singleCourseTemplate->html_requirements( $course ),
169 - 'curriculum' => $this->singleCourseTemplate->html_curriculum( $course, $user ),
170 - 'material' => $this->singleCourseTemplate->html_material( $course, $user ),
171 - 'faqs' => $this->singleCourseTemplate->html_faqs( $course ),
172 - 'instructor' => $this->html_instructor_info( $course, $user ),
173 - 'featured_review_mobile' => $this->singleCourseTemplate->html_feature_review( $course, $user, [ 'lp_display_on' => 'lp-is-mobile' ] ),
174 - 'comment' => $this->singleCourseTemplate->html_comment( $course, $user ),
175 - 'sidebar_mobile' => $this->singleCourseTemplate->html_sidebar( $course, [ 'lp_display_on' => 'lp-is-mobile' ] ),
176 - 'wrapper_end' => '</div>',
177 - ],
178 - $course,
179 - $user
180 - );
181 -
182 - return Template::combine_components( $section );
183 - }
184 -
185 - /**
186 - * HTML right section
187 - *
188 - * @param $course
189 - * @param $user
190 - *
191 - * @return string
192 - */
193 - public function section_right( $course, $user ): string {
194 - $user_id = 0;
195 - if ( $user instanceof UserModel ) {
196 - $user_id = $user->get_id();
197 - }
198 - $userCourseModel = UserCourseModel::find( $user_id, $course->get_id(), true );
199 -
200 - $data_info_meta = [
201 - 'student' => [
202 - 'label' => sprintf( '<i class="lp-icon-user-graduate"></i>%s:', __( 'Student', 'learnpress' ) ),
203 - 'value' => $this->singleCourseTemplate->html_count_student( $course ),
204 - ],
205 - 'lesson' => [
206 - 'label' => sprintf( '<i class="lp-icon-file-o"></i>%s:', __( 'Lesson', 'learnpress' ) ),
207 - 'value' => $this->singleCourseTemplate->html_count_item( $course, LP_LESSON_CPT ),
208 - ],
209 - 'duration' => [
210 - 'label' => sprintf( '<i class="lp-icon-clock-o"></i>%s:', __( 'Duration', 'learnpress' ) ),
211 - 'value' => $this->singleCourseTemplate->html_duration( $course ),
212 - ],
213 - 'quiz' => [
214 - 'label' => sprintf( '<i class="lp-icon-puzzle-piece"></i>%s:', __( 'Quiz', 'learnpress' ) ),
215 - 'value' => $this->singleCourseTemplate->html_count_item( $course, LP_QUIZ_CPT ),
216 - ],
217 - 'level' => [
218 - 'label' => sprintf( '<i class="lp-icon-signal"></i>%s:', __( 'Level', 'learnpress' ) ),
219 - 'value' => $this->singleCourseTemplate->html_level( $course ),
220 - ],
221 - ];
222 -
223 - $data_info_meta = apply_filters( 'learn-press/single-course/modern/info-meta', $data_info_meta, $course, $user );
224 - $html_info_meta = '';
225 - if ( ! empty( $data_info_meta ) ) {
226 - foreach ( $data_info_meta as $info_meta ) {
227 - $label = $info_meta['label'];
228 - $value = $info_meta['value'];
229 - $html_info_two_item = sprintf(
230 - '<div class="info-meta-item">
231 - <span class="info-meta-left">%s</span>
232 - <span class="info-meta-right">%s</span>
233 - </div>',
234 - $label,
235 - $value
236 - );
237 - $html_info_meta .= $html_info_two_item;
238 - }
239 - }
240 -
241 - $section_info_meta = apply_filters(
242 - 'learn-press/single-course/modern/section-right/info-meta',
243 - [
244 - 'wrapper' => '<div class="info-metas">',
245 - 'featured' => $this->singleCourseTemplate->html_featured( $course ),
246 - 'meta' => $html_info_meta,
247 - 'wrapper_end' => '</div>',
248 - ],
249 - $course,
250 - $user
251 - );
252 -
253 - $html_price = '';
254 - if ( ! $userCourseModel || $user_id === 0
255 - || $userCourseModel->get_status() === UserItemModel::STATUS_CANCEL ) {
256 - $html_price = $this->singleCourseTemplate->html_price( $course );
257 - }
258 -
259 - $section = apply_filters(
260 - 'learn-press/single-course/modern/section_right',
261 - [
262 - 'wrapper' => '<div class="lp-single-course-main__right">',
263 - 'wrapper_inner' => '<div class="lp-single-course-main__right__inner">',
264 - 'image' => $this->singleCourseTemplate->html_image( $course ),
265 - 'price' => $html_price,
266 - 'info_learning' => $this->html_info_learning( $course, $user ),
267 - //'sale_discount' => $this->singleCourseTemplate->html_sale_discount( $course ), to do
268 - 'metas' => Template::combine_components( $section_info_meta ),
269 - 'buttons' => $this->html_buttons( $course, $user ),
270 - 'share' => $this->html_share( $course ),
271 - 'featured_review' => $this->singleCourseTemplate->html_feature_review( $course, $user, [ 'lp_display_on' => 'lp-is-pc' ] ),
272 - 'sidebar' => $this->singleCourseTemplate->html_sidebar( $course, [ 'lp_display_on' => 'lp-is-pc' ] ),
273 - 'wrapper_inner_end' => '</div>',
274 - 'wrapper_end' => '</div>',
275 - ],
276 - $course,
277 - $user
278 - );
279 -
280 - return Template::combine_components( $section );
281 - }
282 -
283 - /**
284 - * HTML share social.
285 - *
286 - * @param CourseModel $courseModel
287 - * @param array $data
288 - *
289 - * @return string
290 - * @since 4.2.7.6
291 - * @version 1.0.1
292 - */
293 - public function html_share( CourseModel $courseModel, array $data = [] ): string {
294 - $list_socials = apply_filters(
295 - 'learn-press/single-course/social-share',
296 - [
297 - 'facebook' => [
298 - 'label' => esc_html__( 'Facebook', 'learnpress' ),
299 - 'icon' => '<i class="lp-icon-facebook"></i>',
300 - 'url' => sprintf(
301 - 'https://www.facebook.com/sharer.php?u=%s',
302 - urlencode( $courseModel->get_permalink() )
303 - ),
304 - ],
305 - 'twitter' => [
306 - 'label' => esc_html__( 'Twitter', 'learnpress' ),
307 - 'icon' => '<i class="lp-icon-twitter"></i>',
308 - 'url' => sprintf(
309 - 'https://twitter.com/share?url=%1$s&amp;text=%2$s',
310 - urlencode( $courseModel->get_permalink() ),
311 - rawurlencode( esc_attr( $courseModel->get_title() ) )
312 - ),
313 - ],
314 - 'pinterest' => [
315 - 'label' => esc_html__( 'Pinterest', 'learnpress' ),
316 - 'icon' => '<i class="lp-icon-pinterest-p"></i>',
317 - 'url' => sprintf(
318 - 'https://pinterest.com/pin/create/button/?url=%1$s&amp;description=%2$s&amp;media=%3$s',
319 - urlencode( $courseModel->get_permalink() ),
320 - rawurlencode( esc_attr( $courseModel->get_short_description() ) ),
321 - urlencode( $courseModel->get_image_url() )
322 - ),
323 - ],
324 - 'linkedin' => [
325 - 'label' => esc_html__( 'Linkedin', 'learnpress' ),
326 - 'icon' => '<i class="lp-icon-linkedin"></i>',
327 - 'url' => sprintf(
328 - 'https://www.linkedin.com/shareArticle?mini=true&url=%1$s&title=%2$s&summary=&source=%3$s',
329 - urlencode( $courseModel->get_permalink() ),
330 - esc_attr( $courseModel->get_title() ),
331 - esc_attr( $courseModel->get_short_description() )
332 - ),
333 - ],
334 - ]
335 - );
336 -
337 - $html_social = '';
338 - if ( ! empty( $list_socials ) ) {
339 - foreach ( $list_socials as $key => $social ) {
340 - $html_social .= sprintf(
341 - '<li>
342 - <a target="_blank" href="%s" title="%s">%s<span>%s</span></a>
343 - </li>',
344 - $social['url'],
345 - $social['label'],
346 - $social['icon'],
347 - $social['label']
348 - );
349 - }
350 - } else {
351 - return '';
352 - }
353 -
354 - $social_media = apply_filters(
355 - 'learn-press/single-course/social-share/ul',
356 - [
357 - 'wrapper' => '<ul class="lp-social-media">',
358 - 'content' => $html_social,
359 - 'wrapper_end' => '</ul>',
360 - ]
361 - );
362 -
363 - $clipboard = [
364 - 'wrapper' => '<div class="clipboard-post">',
365 - 'input' => sprintf( '<input class="clipboard-value" type="text" value="%s">', $courseModel->get_permalink() ),
366 - 'button' => sprintf(
367 - '<button class="btn-clipboard" data-copied="%s">%s<span class="tooltip">%s</span></button>',
368 - esc_html__( 'Copied!', 'learnpress' ),
369 - esc_html__( 'Copy', 'learnpress' ),
370 - esc_html__( 'Copy to Clipboard', 'learnpress' )
371 - ),
372 - 'wrapper_end' => '</div>',
373 - ];
374 -
375 - $section = apply_filters(
376 - 'learn-press/single-course/social-share/sections',
377 - [
378 - 'wrapper' => '<div class="social-swapper social-share-toggle">',
379 - 'toggle' => '<div class="share-toggle-icon">',
380 - 'toggle_icon' => sprintf( '<i class="lp-icon-share-alt"></i><label class="share-label">%s</label>', __( 'Share', 'learnpress' ) ),
381 - 'toggle_end' => '</div>',
382 - 'wrapper_content' => '<div class="wrapper-content-widget">',
383 - 'wrapper_content_inner' => '<div class="content-widget-social-share">',
384 - 'clipboard' => Template::combine_components( $clipboard ),
385 - 'social' => Template::combine_components( $social_media ),
386 - 'wrapper_content_inner_end' => '</div>',
387 - 'wrapper_content_end' => '</div>',
388 - 'wrapper_end' => '</div>',
389 - ],
390 - $courseModel,
391 - $data
392 - );
393 -
394 - return Template::combine_components( $section );
395 - }
396 -
397 - /**
398 - * Get html instructor info
399 - *
400 - * @param CourseModel $course
401 - * @param UserModel|false $user
402 - *
403 - * @return string
404 - * @since 4.2.8.3
405 - * @version 1.0.0
406 - */
407 - public function html_instructor_info( CourseModel $course, $user ): string {
408 - $html_instructor = '';
409 - $singleInstructorTemplate = SingleInstructorTemplate::instance();
410 - $author = $course->get_author_model();
411 -
412 - if ( ! $author ) {
413 - return $html_instructor;
414 - }
415 -
416 - $html_instructor_image = sprintf(
417 - '<a href="%s" title="%s">%s</a>',
418 - $author->get_url_instructor(),
419 - $author->get_display_name(),
420 - $singleInstructorTemplate->html_avatar( $author )
421 - );
422 - $section_instructor_meta = [
423 - 'wrapper' => '<div class="lp-instructor-meta">',
424 - 'count_students' => sprintf(
425 - '<div class="instructor-item-meta">%s</div>',
426 - $singleInstructorTemplate->html_count_students( $author )
427 - ),
428 - 'count_courses' => sprintf(
429 - '<div class="instructor-item-meta">%s</div>',
430 - $singleInstructorTemplate->html_count_courses( $author )
431 - ),
432 - 'wrapper_end' => '</div>',
433 - ];
434 - $section_instructor_right = apply_filters(
435 - 'learn-press/single-course/modern/section-instructor/right',
436 - [
437 - 'wrapper' => '<div class="lp-section-instructor">',
438 - 'name' => sprintf(
439 - '<a href="%s">%s</a>',
440 - $author->get_url_instructor(),
441 - $singleInstructorTemplate->html_display_name( $author )
442 - ),
443 - 'meta' => Template::combine_components( $section_instructor_meta ),
444 - 'description' => $singleInstructorTemplate->html_description( $author ),
445 - 'social' => $singleInstructorTemplate->html_social( $author ),
446 - 'wrapper_end' => '</div>',
447 - ],
448 - $course,
449 - $user
450 - );
451 - $section_instructor = apply_filters(
452 - 'learn-press/single-course/modern/section-instructor',
453 - [
454 - 'wrapper' => '<div class="lp-section-instructor">',
455 - 'header' => sprintf( '<h3 class="section-title">%s</h3>', __( 'Instructor', 'learnpress' ) ),
456 - 'wrapper_info' => '<div class="lp-instructor-info">',
457 - 'image' => $html_instructor_image,
458 - 'instructor_right' => Template::combine_components( $section_instructor_right ),
459 - 'wrapper_info_end' => '</div>',
460 - 'wrapper_end' => '</div>',
461 - ],
462 - $course,
463 - $user
464 - );
465 -
466 - if ( ! has_filter( 'learn-press/single-course/modern/section-instructor' ) ) {
467 - // Do not use this hook, this hook only for handle hook without update from Addon, when handle on Addon, will remove this hook
468 - $section_instructor = apply_filters( 'learn-press/single-course/offline/section-instructor', $section_instructor, $course, $user );
469 - }
470 -
471 - return Template::combine_components( $section_instructor );
472 - }
473 -
474 - /**
475 - * Get html course info learning
476 - *
477 - * @param CourseModel $course
478 - * @param UserModel|false $user
479 - *
480 - * @return string
481 - * @since 4.2.8.3
482 - * @version 1.0.1
483 - */
484 - public function html_info_learning( CourseModel $course, $user = false ): string {
485 - $html_info_learning = '';
486 - $user_id = 0;
487 - if ( $user instanceof UserModel ) {
488 - $user_id = $user->get_id();
489 - } else {
490 - return $html_info_learning;
491 - }
492 -
493 - $userCourseModel = UserCourseModel::find( $user_id, $course->get_id(), true );
494 - if ( $userCourseModel instanceof UserCourseModel
495 - && $userCourseModel->get_status() !== UserItemModel::STATUS_CANCEL
496 - && $userCourseModel->get_status() !== UserCourseModel::STATUS_PURCHASED ) {
497 - $userCourseTemplate = UserCourseTemplate::instance();
498 - $html_end_date = '';
499 - $html_graduation = '';
500 -
501 - if ( $userCourseModel->has_finished() ) {
502 - $html_end_date = sprintf(
503 - '<div class="end-date">%s: %s</div>',
504 - __( 'End date', 'learnpress' ),
505 - $userCourseTemplate->html_end_date_time( $userCourseModel, false )
506 - );
507 - $html_graduation = $userCourseTemplate->html_graduation( $userCourseModel );
508 - }
509 -
510 - $section_info_learning = [
511 - 'wrapper' => '<div class="info-learning">',
512 - 'message_lock' => $userCourseTemplate->html_message_lock( $userCourseModel ),
513 - 'graduation' => $html_graduation,
514 - 'progress' => $userCourseTemplate->html_progress( $userCourseModel ),
515 - 'start_date' => sprintf(
516 - '<div class="start-date">%s: %s</div>',
517 - __( 'Start date', 'learnpress' ),
518 - $userCourseTemplate->html_start_date_time( $userCourseModel, false )
519 - ),
520 - 'end_date' => $html_end_date,
521 - 'count_items_completed' => $userCourseTemplate->html_count_items_completed( $userCourseModel ),
522 - 'wrapper_end' => '</div>',
523 - ];
524 -
525 - $html_info_learning = Template::combine_components( $section_info_learning );
526 - }
527 -
528 - return $html_info_learning;
529 - }
530 -
531 - /**
532 - * Get html button
533 - *
534 - * @param CourseModel $course
535 - * @param UserModel|false $user
536 - *
537 - * @return string
538 - * @since 4.2.8.3
539 - * @version 1.0.1
540 - */
541 - public function html_buttons( CourseModel $course, $user = false ): string {
542 - $user_id = 0;
543 - if ( $user instanceof UserModel ) {
544 - $user_id = $user->get_id();
545 - }
546 -
547 - $userCourseModel = UserCourseModel::find( $user_id, $course->get_id(), true );
548 - $btn_continue_and_finish = [];
549 - if ( $userCourseModel instanceof UserCourseModel ) {
550 - $userCourseTemplate = UserCourseTemplate::instance();
551 - $btn_continue_and_finish = [
552 - 'btn_continue' => $userCourseTemplate->html_btn_continue( $userCourseModel ),
553 - 'btn_finish' => $userCourseTemplate->html_btn_finish( $userCourseModel ),
554 - 'btn_retake' => $userCourseTemplate->html_btn_retake( $userCourseModel ),
555 - ];
556 - }
557 -
558 - $section_buttons = apply_filters(
559 - 'learn-press/single-course/modern/section-right/buttons',
560 - [
561 - 'wrapper' => '<div class="course-buttons">',
562 - 'btn_contact' => SingleCourseTemplate::instance()->html_btn_external( $course, $user ),
563 - 'btn_buy' => SingleCourseTemplate::instance()->html_btn_purchase_course( $course, $user ),
564 - 'btn_enroll' => SingleCourseTemplate::instance()->html_btn_enroll_course( $course, $user ),
565 - 'btn_learning' => Template::combine_components( $btn_continue_and_finish ),
566 - 'wrapper_end' => '</div>',
567 - ],
568 - $course,
569 - $user
570 - );
571 -
572 - return Template::combine_components( $section_buttons );
573 - }
574 -}
1 +<?php
2 +/**
3 + * Template hooks Single Course Online.
4 + *
5 + * @since 4.2.7
6 + * @version 1.0.0
7 + */
8 +
9 +namespace LearnPress\TemplateHooks\Course;
10 +
11 +use LearnPress\Helpers\Singleton;
12 +use LearnPress\Helpers\Template;
13 +use LearnPress\Models\CourseModel;
14 +use LearnPress\Models\UserItems\UserCourseModel;
15 +use LearnPress\Models\UserItems\UserItemModel;
16 +use LearnPress\TemplateHooks\UserItem\UserCourseTemplate;
17 +use LearnPress\Models\UserModel;
18 +use LearnPress\TemplateHooks\Instructor\SingleInstructorTemplate;
19 +use LP_Datetime;
20 +
21 +class SingleCourseModernLayout {
22 + use Singleton;
23 +
24 + /**
25 + * @var SingleCourseTemplate
26 + */
27 + public $singleCourseTemplate;
28 +
29 + public function init(): void {
30 + $this->singleCourseTemplate = SingleCourseTemplate::instance();
31 +
32 + add_action(
33 + 'learn-press/single-course/layout',
34 + [ $this, 'course_model_layout' ]
35 + );
36 + }
37 +
38 + /**
39 + * Single course layout model
40 + *
41 + * @param $course
42 + *
43 + * @return void
44 + */
45 + public function course_model_layout( $course ) {
46 + if ( ! $course instanceof CourseModel ) {
47 + return;
48 + }
49 +
50 + $user = UserModel::find( get_current_user_id(), true );
51 +
52 + // Related courses
53 + ob_start();
54 + do_action( 'learn-press/single-course/courses-related/layout', $course, 4 );
55 + $html_courses_related = ob_get_clean();
56 +
57 + $sections = apply_filters(
58 + 'learn-press/single-course/modern/sections',
59 + [
60 + 'wrapper' => '<div class="lp-single-course">',
61 + 'section_header' => $this->header_sections( $course, $user ),
62 + 'wrapper_container' => '<div class="lp-content-area">',
63 + 'wrapper_main' => '<div class="lp-single-course-main">',
64 + 'section_left' => $this->section_left( $course, $user ),
65 + 'section_right' => $this->section_right( $course, $user ),
66 + 'wrapper_main_end' => '</div>',
67 + 'related_courses' => $html_courses_related,
68 + 'wrapper_container_end' => '</div>',
69 + 'wrapper_end' => '</div>',
70 + ]
71 + );
72 +
73 + echo Template::combine_components( $sections );
74 + }
75 +
76 + /**
77 + * HTML header section
78 + *
79 + * @param $course
80 + * @param $user
81 + *
82 + * @return string
83 + */
84 + public function header_sections( $course, $user ): string {
85 + $html_categories = $this->singleCourseTemplate->html_categories( $course );
86 + if ( ! empty( $html_categories ) ) {
87 + $html_categories = sprintf(
88 + '<div>%s %s</div>',
89 + sprintf( '<label>%s</label>', esc_html__( 'in', 'learnpress' ) ),
90 + $html_categories
91 + );
92 + }
93 +
94 + $section_info_one = apply_filters(
95 + 'learn-press/single-course/modern/header/info-meta',
96 + [
97 + 'wrapper' => '<div class="lp-single-course-info-one">',
98 + 'author' => '',
99 + 'last_update' => sprintf(
100 + '<div class="item-meta">%s: %s</div>',
101 + esc_html__( 'Last updated', 'learnpress' ),
102 + esc_attr( get_post_modified_time( get_option( 'date_format' ), true ) )
103 + ),
104 + 'wrapper_end' => '</div>',
105 + ],
106 + $course,
107 + $user
108 + );
109 + if ( ! has_filter( 'learn-press/single-course/modern/header/info-meta' ) ) {
110 + // Do not use this hook, this hook only for handle hook without update from Addon, when handle on Addon, will remove this hook
111 + $section_info_one = apply_filters(
112 + 'learn-press/single-course/offline/info-bar',
113 + $section_info_one,
114 + $course,
115 + $user
116 + );
117 + }
118 +
119 + $html_instructor = sprintf(
120 + '<div>%s %s</div>',
121 + sprintf( '<label>%s</label>', esc_html__( 'by', 'learnpress' ) ),
122 + $this->singleCourseTemplate->html_instructor( $course )
123 + );
124 +
125 + $header_sections = apply_filters(
126 + 'learn-press/single-course/modern/header/sections',
127 + [
128 + 'wrapper_header' => '<div class="lp-single-course__header">',
129 + 'wrapper_container' => '<div class="lp-single-course__header__inner">',
130 + 'breadcrumb' => Template::html_breadcrumb(),
131 + 'title' => $this->singleCourseTemplate->html_title( $course, 'h1' ),
132 + 'wrapper_instructor_cate' => '<div class="course-instructor-category">',
133 + 'instructor' => $html_instructor,
134 + 'category' => $html_categories,
135 + 'wrapper_instructor_cate_end' => '</div>',
136 + 'info_one' => Template::combine_components( $section_info_one ),
137 + 'wrapper_container_end' => '</div>',
138 + 'wrapper_header_end' => '</div>',
139 + ],
140 + $course,
141 + $user
142 + );
143 +
144 + return Template::combine_components( $header_sections );
145 + }
146 +
147 + /**
148 + * HTML left section
149 + *
150 + * @param $course
151 + * @param $user
152 + *
153 + * @return string
154 + */
155 + public function section_left( $course, $user ): string {
156 + // Global message
157 + ob_start();
158 + learn_press_show_message();
159 + $global_message = ob_get_clean();
160 +
161 + $section = apply_filters(
162 + 'learn-press/single-course/modern/section_left',
163 + [
164 + 'wrapper' => '<div class="lp-single-course-main__left">',
165 + 'global_message' => $global_message,
166 + 'description' => $this->singleCourseTemplate->html_description( $course ),
167 + 'features' => $this->singleCourseTemplate->html_features( $course ),
168 + 'target' => $this->singleCourseTemplate->html_target( $course ),
169 + 'requirements' => $this->singleCourseTemplate->html_requirements( $course ),
170 + 'curriculum' => $this->singleCourseTemplate->html_curriculum( $course, $user ),
171 + 'material' => $this->singleCourseTemplate->html_material( $course, $user ),
172 + 'faqs' => $this->singleCourseTemplate->html_faqs( $course ),
173 + 'instructor' => $this->html_instructor_info( $course, $user ),
174 + 'featured_review_mobile' => $this->singleCourseTemplate->html_feature_review( $course, $user, [ 'lp_display_on' => 'lp-is-mobile' ] ),
175 + 'comment' => $this->singleCourseTemplate->html_comment( $course, $user ),
176 + 'sidebar_mobile' => $this->singleCourseTemplate->html_sidebar( $course, [ 'lp_display_on' => 'lp-is-mobile' ] ),
177 + 'wrapper_end' => '</div>',
178 + ],
179 + $course,
180 + $user
181 + );
182 +
183 + return Template::combine_components( $section );
184 + }
185 +
186 + /**
187 + * HTML right section
188 + *
189 + * @param $course
190 + * @param $user
191 + *
192 + * @return string
193 + */
194 + public function section_right( $course, $user ): string {
195 + $user_id = 0;
196 + if ( $user instanceof UserModel ) {
197 + $user_id = $user->get_id();
198 + }
199 + $userCourseModel = UserCourseModel::find( $user_id, $course->get_id(), true );
200 +
201 + $data_info_meta = [
202 + 'student' => [
203 + 'label' => sprintf( '<i class="lp-icon-user-graduate"></i>%s:', esc_html__( 'Student', 'learnpress' ) ),
204 + 'value' => $this->singleCourseTemplate->html_count_student( $course ),
205 + ],
206 + 'lesson' => [
207 + 'label' => sprintf( '<i class="lp-icon-file-o"></i>%s:', esc_html__( 'Lesson', 'learnpress' ) ),
208 + 'value' => $this->singleCourseTemplate->html_count_item( $course, LP_LESSON_CPT ),
209 + ],
210 + 'duration' => [
211 + 'label' => sprintf( '<i class="lp-icon-clock-o"></i>%s:', esc_html__( 'Duration', 'learnpress' ) ),
212 + 'value' => $this->singleCourseTemplate->html_duration( $course ),
213 + ],
214 + 'quiz' => [
215 + 'label' => sprintf( '<i class="lp-icon-puzzle-piece"></i>%s:', esc_html__( 'Quiz', 'learnpress' ) ),
216 + 'value' => $this->singleCourseTemplate->html_count_item( $course, LP_QUIZ_CPT ),
217 + ],
218 + 'level' => [
219 + 'label' => sprintf( '<i class="lp-icon-signal"></i>%s:', esc_html__( 'Level', 'learnpress' ) ),
220 + 'value' => $this->singleCourseTemplate->html_level( $course ),
221 + ],
222 + ];
223 +
224 + $data_info_meta = apply_filters( 'learn-press/single-course/modern/info-meta', $data_info_meta, $course, $user );
225 + $html_info_meta = '';
226 + if ( ! empty( $data_info_meta ) ) {
227 + foreach ( $data_info_meta as $info_meta ) {
228 + $label = $info_meta['label'];
229 + $value = $info_meta['value'];
230 + $html_info_two_item = sprintf(
231 + '<div class="info-meta-item">
232 + <span class="info-meta-left">%s</span>
233 + <span class="info-meta-right">%s</span>
234 + </div>',
235 + $label,
236 + $value
237 + );
238 + $html_info_meta .= $html_info_two_item;
239 + }
240 + }
241 +
242 + $section_info_meta = apply_filters(
243 + 'learn-press/single-course/modern/section-right/info-meta',
244 + [
245 + 'wrapper' => '<div class="info-metas">',
246 + 'featured' => $this->singleCourseTemplate->html_featured( $course ),
247 + 'meta' => $html_info_meta,
248 + 'wrapper_end' => '</div>',
249 + ],
250 + $course,
251 + $user
252 + );
253 +
254 + $html_price = '';
255 + if ( ! $userCourseModel || $user_id === 0
256 + || $userCourseModel->get_status() === UserItemModel::STATUS_CANCEL ) {
257 + $html_price = $this->singleCourseTemplate->html_price( $course );
258 + }
259 +
260 + $section = apply_filters(
261 + 'learn-press/single-course/modern/section_right',
262 + [
263 + 'wrapper' => '<div class="lp-single-course-main__right">',
264 + 'wrapper_inner' => '<div class="lp-single-course-main__right__inner">',
265 + 'image' => $this->singleCourseTemplate->html_image( $course ),
266 + 'price' => $html_price,
267 + 'info_learning' => $this->html_info_learning( $course, $user ),
268 + //'sale_discount' => $this->singleCourseTemplate->html_sale_discount( $course ), to do
269 + 'metas' => Template::combine_components( $section_info_meta ),
270 + 'buttons' => $this->html_buttons( $course, $user ),
271 + 'share' => $this->html_share( $course ),
272 + 'featured_review' => $this->singleCourseTemplate->html_feature_review( $course, $user, [ 'lp_display_on' => 'lp-is-pc' ] ),
273 + 'sidebar' => $this->singleCourseTemplate->html_sidebar( $course, [ 'lp_display_on' => 'lp-is-pc' ] ),
274 + 'wrapper_inner_end' => '</div>',
275 + 'wrapper_end' => '</div>',
276 + ],
277 + $course,
278 + $user
279 + );
280 +
281 + return Template::combine_components( $section );
282 + }
283 +
284 + /**
285 + * HTML share social.
286 + *
287 + * @param CourseModel $courseModel
288 + * @param array $data
289 + *
290 + * @return string
291 + * @since 4.2.7.6
292 + * @version 1.0.1
293 + */
294 + public function html_share( CourseModel $courseModel, array $data = [] ): string {
295 + $list_socials = apply_filters(
296 + 'learn-press/single-course/social-share',
297 + [
298 + 'facebook' => [
299 + 'label' => esc_html__( 'Facebook', 'learnpress' ),
300 + 'icon' => '<i class="lp-icon-facebook"></i>',
301 + 'url' => sprintf(
302 + 'https://www.facebook.com/sharer.php?u=%s',
303 + urlencode( $courseModel->get_permalink() )
304 + ),
305 + ],
306 + 'twitter' => [
307 + 'label' => esc_html__( 'Twitter', 'learnpress' ),
308 + 'icon' => '<i class="lp-icon-twitter"></i>',
309 + 'url' => sprintf(
310 + 'https://twitter.com/share?url=%1$s&amp;text=%2$s',
311 + urlencode( $courseModel->get_permalink() ),
312 + rawurlencode( esc_attr( $courseModel->get_title() ) )
313 + ),
314 + ],
315 + 'pinterest' => [
316 + 'label' => esc_html__( 'Pinterest', 'learnpress' ),
317 + 'icon' => '<i class="lp-icon-pinterest-p"></i>',
318 + 'url' => sprintf(
319 + 'https://pinterest.com/pin/create/button/?url=%1$s&amp;description=%2$s&amp;media=%3$s',
320 + urlencode( $courseModel->get_permalink() ),
321 + rawurlencode( esc_attr( $courseModel->get_short_description() ) ),
322 + urlencode( $courseModel->get_image_url() )
323 + ),
324 + ],
325 + 'linkedin' => [
326 + 'label' => esc_html__( 'Linkedin', 'learnpress' ),
327 + 'icon' => '<i class="lp-icon-linkedin"></i>',
328 + 'url' => sprintf(
329 + 'https://www.linkedin.com/shareArticle?mini=true&url=%1$s&title=%2$s&summary=&source=%3$s',
330 + urlencode( $courseModel->get_permalink() ),
331 + esc_attr( $courseModel->get_title() ),
332 + esc_attr( $courseModel->get_short_description() )
333 + ),
334 + ],
335 + ]
336 + );
337 +
338 + $html_social = '';
339 + if ( ! empty( $list_socials ) ) {
340 + foreach ( $list_socials as $key => $social ) {
341 + $html_social .= sprintf(
342 + '<li>
343 + <a target="_blank" href="%s" title="%s">%s<span>%s</span></a>
344 + </li>',
345 + esc_url_raw( $social['url'] ?? '' ),
346 + esc_attr( $social['label'] ?? '' ),
347 + Template::sanitize_html_content( $social['icon'] ?? '' ),
348 + esc_html( $social['label'] ?? '' )
349 + );
350 + }
351 + } else {
352 + return '';
353 + }
354 +
355 + $social_media = apply_filters(
356 + 'learn-press/single-course/social-share/ul',
357 + [
358 + 'wrapper' => '<ul class="lp-social-media">',
359 + 'content' => $html_social,
360 + 'wrapper_end' => '</ul>',
361 + ]
362 + );
363 +
364 + $clipboard = [
365 + 'wrapper' => '<div class="clipboard-post">',
366 + 'input' => sprintf(
367 + '<input class="clipboard-value" type="text" value="%s">',
368 + esc_url( $courseModel->get_permalink() )
369 + ),
370 + 'button' => sprintf(
371 + '<button class="btn-clipboard" data-copied="%s">%s<span class="tooltip">%s</span></button>',
372 + esc_attr__( 'Copied!', 'learnpress' ),
373 + esc_html__( 'Copy', 'learnpress' ),
374 + esc_html__( 'Copy to Clipboard', 'learnpress' )
375 + ),
376 + 'wrapper_end' => '</div>',
377 + ];
378 +
379 + $section = apply_filters(
380 + 'learn-press/single-course/social-share/sections',
381 + [
382 + 'wrapper' => '<div class="social-swapper social-share-toggle">',
383 + 'toggle' => '<div class="share-toggle-icon">',
384 + 'toggle_icon' => sprintf(
385 + '<i class="lp-icon-share-alt"></i>
386 + <label class="share-label">%s</label>',
387 + esc_html__( 'Share', 'learnpress' )
388 + ),
389 + 'toggle_end' => '</div>',
390 + 'wrapper_content' => '<div class="wrapper-content-widget">',
391 + 'wrapper_content_inner' => '<div class="content-widget-social-share">',
392 + 'clipboard' => Template::combine_components( $clipboard ),
393 + 'social' => Template::combine_components( $social_media ),
394 + 'wrapper_content_inner_end' => '</div>',
395 + 'wrapper_content_end' => '</div>',
396 + 'wrapper_end' => '</div>',
397 + ],
398 + $courseModel,
399 + $data
400 + );
401 +
402 + return Template::combine_components( $section );
403 + }
404 +
405 + /**
406 + * Get html instructor info
407 + *
408 + * @param CourseModel $course
409 + * @param UserModel|false $user
410 + *
411 + * @return string
412 + * @since 4.2.8.3
413 + * @version 1.0.0
414 + */
415 + public function html_instructor_info( CourseModel $course, $user ): string {
416 + $html_instructor = '';
417 + $singleInstructorTemplate = SingleInstructorTemplate::instance();
418 + $author = $course->get_author_model();
419 +
420 + if ( ! $author ) {
421 + return $html_instructor;
422 + }
423 +
424 + $html_instructor_image = sprintf(
425 + '<a href="%s" title="%s">%s</a>',
426 + esc_url( $author->get_url_instructor() ),
427 + esc_attr( $author->get_display_name() ),
428 + $singleInstructorTemplate->html_avatar( $author )
429 + );
430 + $section_instructor_meta = [
431 + 'wrapper' => '<div class="lp-instructor-meta">',
432 + 'count_students' => sprintf(
433 + '<div class="instructor-item-meta">%s</div>',
434 + $singleInstructorTemplate->html_count_students( $author )
435 + ),
436 + 'count_courses' => sprintf(
437 + '<div class="instructor-item-meta">%s</div>',
438 + $singleInstructorTemplate->html_count_courses( $author )
439 + ),
440 + 'wrapper_end' => '</div>',
441 + ];
442 + $section_instructor_right = apply_filters(
443 + 'learn-press/single-course/modern/section-instructor/right',
444 + [
445 + 'wrapper' => '<div class="lp-section-instructor">',
446 + 'name' => sprintf(
447 + '<a href="%s">%s</a>',
448 + esc_url( $author->get_url_instructor() ),
449 + $singleInstructorTemplate->html_display_name( $author )
450 + ),
451 + 'meta' => Template::combine_components( $section_instructor_meta ),
452 + 'description' => $singleInstructorTemplate->html_description( $author ),
453 + 'social' => $singleInstructorTemplate->html_social( $author ),
454 + 'wrapper_end' => '</div>',
455 + ],
456 + $course,
457 + $user
458 + );
459 + $section_instructor = apply_filters(
460 + 'learn-press/single-course/modern/section-instructor',
461 + [
462 + 'wrapper' => '<div class="lp-section-instructor">',
463 + 'header' => sprintf(
464 + '<h3 class="section-title">%s</h3>',
465 + esc_html__( 'Instructor', 'learnpress' )
466 + ),
467 + 'wrapper_info' => '<div class="lp-instructor-info">',
468 + 'image' => $html_instructor_image,
469 + 'instructor_right' => Template::combine_components( $section_instructor_right ),
470 + 'wrapper_info_end' => '</div>',
471 + 'wrapper_end' => '</div>',
472 + ],
473 + $course,
474 + $user
475 + );
476 +
477 + if ( ! has_filter( 'learn-press/single-course/modern/section-instructor' ) ) {
478 + // Do not use this hook, this hook only for handle hook without update from Addon, when handle on Addon, will remove this hook
479 + $section_instructor = apply_filters(
480 + 'learn-press/single-course/offline/section-instructor',
481 + $section_instructor,
482 + $course,
483 + $user
484 + );
485 + }
486 +
487 + return Template::combine_components( $section_instructor );
488 + }
489 +
490 + /**
491 + * Get html course info learning
492 + *
493 + * @param CourseModel $course
494 + * @param UserModel|false $user
495 + *
496 + * @return string
497 + * @since 4.2.8.3
498 + * @version 1.0.2
499 + */
500 + public function html_info_learning( CourseModel $course, $user = false ): string {
501 + $html_info_learning = '';
502 + $user_id = 0;
503 + if ( $user instanceof UserModel ) {
504 + $user_id = $user->get_id();
505 + } else {
506 + return $html_info_learning;
507 + }
508 +
509 + $userCourseModel = UserCourseModel::find( $user_id, $course->get_id(), true );
510 + if ( $userCourseModel instanceof UserCourseModel
511 + && $userCourseModel->get_status() !== UserItemModel::STATUS_CANCEL
512 + && $userCourseModel->get_status() !== UserCourseModel::STATUS_PURCHASED ) {
513 + $userCourseTemplate = UserCourseTemplate::instance();
514 + $html_end_date = '';
515 + $html_graduation = '';
516 + $html_will_end_date = '';
517 +
518 + if ( $userCourseModel->has_finished() ) {
519 + $html_end_date = sprintf(
520 + '<div class="end-date">%s: %s</div>',
521 + esc_html__( 'End date', 'learnpress' ),
522 + $userCourseTemplate->html_end_date_time( $userCourseModel, false )
523 + );
524 + $html_graduation = $userCourseTemplate->html_graduation( $userCourseModel );
525 + } else {
526 + $started_date = $userCourseModel->get_start_time();
527 + $duration = $course->get_duration();
528 + $will_end_date = new LP_Datetime( strtotime( "+ $duration", strtotime( $started_date ) ) );
529 + $will_end_date = $will_end_date->format( LP_Datetime::I18N_FORMAT );
530 + $html_will_end_date = sprintf(
531 + '<div class="will-end-date">%s: %s</div>',
532 + esc_html__( 'Expiry date', 'learnpress' ),
533 + $will_end_date
534 + );
535 + }
536 +
537 + $section_info_learning = apply_filters(
538 + 'learn-press/single-course/modern/section-info-learning',
539 + [
540 + 'wrapper' => '<div class="info-learning">',
541 + 'message_lock' => $userCourseTemplate->html_message_lock( $userCourseModel ),
542 + 'graduation' => $html_graduation,
543 + 'progress' => $userCourseTemplate->html_progress( $userCourseModel ),
544 + 'start_date' => sprintf(
545 + '<div class="start-date">%s: %s</div>',
546 + esc_html__( 'Start date', 'learnpress' ),
547 + $userCourseTemplate->html_start_date_time( $userCourseModel, false )
548 + ),
549 + 'will_end_date' => $html_will_end_date,
550 + 'end_date' => $html_end_date,
551 + 'count_items_completed' => $userCourseTemplate->html_count_items_completed( $userCourseModel ),
552 + 'wrapper_end' => '</div>',
553 + ],
554 + $course,
555 + $user
556 + );
557 +
558 + $html_info_learning = Template::combine_components( $section_info_learning );
559 + }
560 +
561 + return $html_info_learning;
562 + }
563 +
564 + /**
565 + * Get html button
566 + *
567 + * @param CourseModel $course
568 + * @param UserModel|false $user
569 + *
570 + * @return string
571 + * @since 4.2.8.3
572 + * @version 1.0.1
573 + */
574 + public function html_buttons( CourseModel $course, $user = false ): string {
575 + $user_id = 0;
576 + if ( $user instanceof UserModel ) {
577 + $user_id = $user->get_id();
578 + }
579 +
580 + $userCourseModel = UserCourseModel::find( $user_id, $course->get_id(), true );
581 + $btn_continue_and_finish = [];
582 + if ( $userCourseModel instanceof UserCourseModel ) {
583 + $userCourseTemplate = UserCourseTemplate::instance();
584 + $btn_continue_and_finish = [
585 + 'btn_continue' => $userCourseTemplate->html_btn_continue( $userCourseModel ),
586 + 'btn_finish' => $userCourseTemplate->html_btn_finish( $userCourseModel ),
587 + 'btn_retake' => $userCourseTemplate->html_btn_retake( $userCourseModel ),
588 + ];
589 + }
590 +
591 + $section_buttons = apply_filters(
592 + 'learn-press/single-course/modern/section-right/buttons',
593 + [
594 + 'wrapper' => '<div class="course-buttons">',
595 + 'btn_contact' => SingleCourseTemplate::instance()->html_btn_external( $course, $user ),
596 + 'btn_buy' => SingleCourseTemplate::instance()->html_btn_purchase_course( $course, $user ),
597 + 'btn_enroll' => SingleCourseTemplate::instance()->html_btn_enroll_course( $course, $user ),
598 + 'btn_learning' => Template::combine_components( $btn_continue_and_finish ),
599 + 'wrapper_end' => '</div>',
600 + ],
601 + $course,
602 + $user
603 + );
604 +
605 + return Template::combine_components( $section_buttons );
606 + }
607 +}