PluginProbe
WP Courses LMS – Online Courses Builder, eLearning Courses, Courses Solution, Education Courses / trunk
WP Courses LMS – Online Courses Builder, eLearning Courses, Courses Solution, Education Courses vtrunk
3.2.30 trunk 3.1.40 3.1.41 3.1.42 3.1.43 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.17 3.2.18 3.2.19 3.2.2 3.2.20 3.2.21 3.2.22 3.2.23 3.2.24 3.2.25 All 36 releases
wp-courses / functions / output.php

output.php in WP Courses LMS – Online Courses Builder, eLearning Courses, Courses Solution, Education Courses trunk, at functions/output.php

856 lines 31.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @param Int $id ID of the lesson or course
5 * @param string $type Accepts post type of course or lesson
6 * @return Course or lesson video iframe from lesson-video or course-video post_meta
7 */
8
9 function wpc_get_video($id, $type = 'lesson'){
10
11 $video = $type == 'lesson' ? get_post_meta( $id, 'lesson-video', true ) : get_post_meta( $id, 'course-video', true );
12
13 if(empty($video)){
14 $video = false;
15 } elseif( strpos( $video, '[' ) !== false ){
16 $video = do_shortcode($video);
17 } elseif( strpos( $video, 'iframe' ) !== false || strpos( $video, '<video' ) !== false ){
18 // it's an iframe or <video>, so return as is
19 $video = $video;
20 } elseif(strpos($video, 'youtu.be' )){
21 // it's a YT video with shortened url
22 $video = str_replace('youtube.be/', 'https://www.youtube.com/watch?v=', $video);
23 $video = wp_oembed_get( $video );
24 }elseif( strpos($video, 'youtube.com' ) || strpos($video, 'vimeo.com')) {
25 // it's a youtube or vimeo video using a url
26 $video = wp_oembed_get( $video );
27 } elseif( preg_match("/[a-z]/i", $video) || preg_match("/[A-Z]/i", $video )){
28 // it's a YT video with code only (ie. CvL5Amq0e8w)
29 $video = '<iframe class="wpc-video" id="video-iframe" width="560" height="315" src="https://www.youtube.com/embed/' . $video . '" frameborder="0" allowfullscreen></iframe>';
30 } elseif( preg_match("/[a-z]/i", $video) == 0 || preg_match("/[A-Z]/i", $video) == 0 ){
31 // it's not a YT video with code only (ie. CvL5Amq0e8w). Assumed to be Vimeo.
32 $video = '<iframe class="wpc-video" id="video-iframe" src="https://player.vimeo.com/video/' . $video . '" width="500" height="216" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
33 }
34
35 if(has_filter( 'wpc_lesson_video' )){
36 $video = apply_filters( 'wpc_lesson_video', $video );
37 }
38
39 $video = wpc_sanitize_video($video);
40
41 return $video;
42
43 }
44
45 /**
46 * Returns unordered list of all course categories
47 * @param String $active_category_slug if category slug is passed, the class wpc-active-nav-item will be added to the active category li. Pass true to select the "all" category.
48 * @return Ul of all course categories
49 */
50
51 function wpc_get_course_category_list($active_category_slug = true){
52
53 $categories = get_terms('course-category');
54
55 $html = '<ul class="wpc-nav-list wpc-nav-list-contained">';
56 $html .= '<li><a id="wpc-all-categories-button" href="' . get_post_type_archive_link( 'course' ) . '" class="' . $active_category_slug . '">' . esc_html( __('All', 'wp-courses') ) . '</a></li>';
57 if(!empty($categories)){
58 foreach($categories as $category){
59 $html .= '<li><a href="' . get_term_link($category) . '" class="' . $active_category_slug . '">' . $category->name . '</a></li>';
60 }
61 } else {
62 return false;
63 }
64 $html .= '</ul>';
65
66 if( has_filter( 'wpc_course_category_list' ) ){
67 $html = apply_filters( 'wpc_course_category_list', $html );
68 }
69
70 return $html;
71 }
72
73
74 /**
75 * @return Unordered list of all published and draft courses
76 */
77
78 function wpc_get_course_list(){
79 $course_args = array(
80 'post_type' => 'course',
81 'nopaging' => true,
82 'order' => 'ASC',
83 'orderby' => 'menu_order',
84 'post_status' => array('publish', 'draft'),
85 );
86 $course_query = new WP_Query($course_args);
87 $html = '<ul class="wpc-nav-list wpc-nav-list-contained wpc-course-list">';
88 while($course_query->have_posts()){
89 $course_query->the_post();
90 $post_id = get_the_ID();
91 $display_status = (get_post_status( $post_id ) == 'draft') ? ' (draft)' : '';
92 $html .= '<li class="wpc-course-list-li" data-id="' . $post_id . '"><i class="fa-solid fa-grip"></i> ' . get_the_title() . $display_status . '</li>';
93 }
94 $html .= '</ul>';
95 wp_reset_postdata();
96 return $html;
97 }
98
99 /**
100 * Returns radio buttons for setting lesson restriction
101 * @param int $lesson_id Tthe lesson you'd like to set the restriction for
102 * @param string $name Sets the name parameter value for the radio buttons
103 * @param string $class Assigns a class to each radio button
104 * @return Radio buttons for restricting lesson content
105 */
106
107 function wpc_lesson_restriction_radio_buttons($lesson_id, $name = 'wpc-lesson-restriction', $class = 'lesson-restriction-radio'){
108
109 $lesson_restriction = get_post_meta($lesson_id, 'wpc-lesson-restriction', true);
110
111 if(empty($lesson_restriction)){
112 $lesson_restriction = 'none';
113 }
114
115 $html = '<div class="wpc-radio-buttons">';
116
117 $html .= '<div class="wpc-metabox-item">';
118 $html .= ' <button type="button" class="wpc-question-btn wpc-btn wpc-btn-sm" data-content="Anyone visiting your website can view this lesson."><i class="fa fa-question"></i> </button>';
119
120 $html .= '<input id="wpc-none-radio" class="' . $class . '" type="radio" name="' . $name . '" value="none" data-id="' . $lesson_id . '"';
121 $html .= checked($lesson_restriction, 'none', false);
122 $html .= '/> None<br>';
123 $html .= '</div>';
124
125 $html .= '<div class="wpc-metabox-item">';
126 $html .= ' <button type="button" class="wpc-question-btn wpc-btn wpc-btn-sm" data-content="Users must have an account on your WordPress website and must be logged in to view the contents of this lesson."><i class="fa fa-question"></i> </button>';
127 $html .= '<input id="wpc-free-account-radio" class="' . $class . '" type="radio" name="' . $name . '" value="free-account" data-id="' . $lesson_id . '"';
128 $html .= checked($lesson_restriction, 'free-account', false);
129 $html .= '/> Login Required';
130 $html .= '</div>';
131
132 if(has_filter('wpc_lesson_restriction_radio_buttons')){
133 $html = apply_filters( 'wpc_lesson_restriction_radio_buttons', $html, $lesson_id );
134 }
135
136 // Hidden membership field
137 $html .= '<input style="display:none;" id="wpc-membership-radio" class="' . $class . '" type="radio" name="' . $name . '" value="membership" data-id="' . $lesson_id . '"';
138 $html .= checked($lesson_restriction, 'membership', false);
139 $html .= '/>';
140 $html .= '</div>';
141
142 return $html;
143 }
144
145 /**
146 * Returns the correct status icon for lessons and quizzes.
147 * @param int $user_id
148 * @param int $post_id Should be the ID of either the lesson or quiz you'd like to get the status icon for
149 * @param string $post_type Accepts either lesson or wpc-quiz
150 * @return Fa icons html icon
151 */
152
153 function get_lesson_icon($user_id, $post_id, $post_type = 'lesson'){
154
155 $restriction = get_post_meta( $post_id, 'wpc-lesson-restriction', true );
156
157 if( is_user_logged_in() ){ // User logged in
158 if($post_type === 'lesson'){ // Lesson
159 $status = wpc_get_lesson_status($user_id, $post_id);
160 $viewed = (int) $status['viewed'];
161 $completed = (int) $status['completed'];
162
163 if($completed === 1){
164 $icon = '<i class="fa-regular fa-square-check wpc-default-status"></i>'; // Completed
165 } elseif($viewed === 1) {
166 $icon = '<i class="fa-regular fa-square wpc-default-status"></i>'; // Viewed
167 } else {
168 $icon = '<i class="fa-regular fa-square wpc-default-status"></i>'; // Not viewed so far
169 }
170 } else { // Quiz
171 $icon = '<i class="fa-solid fa-graduation-cap"></i>';
172 }
173
174 // Overwrite icon if content drip is active and duration is not over
175 if (function_exists('wpc_woo_has_bought')) {
176 $has_bought = wpc_woo_has_bought($post_id);
177
178 if($has_bought == true) {
179 $lesson_content_drip_days = get_post_meta($post_id, 'wpc-lesson-content-drip-days', true);
180
181 if(!empty($lesson_content_drip_days)) {
182 $timestamp = wpc_timestamp_drip_lesson_content($post_id, $lesson_content_drip_days);
183
184 if ($timestamp !== 0) {
185 $icon = '<i class="fa-regular fa-hourglass"></i>';
186 }
187 }
188 }
189 }
190 } else { // User logged out
191 if($restriction == 'none'){
192 if($post_type === 'lesson'){ // Lesson
193 $icon = '<i class="fa-regular fa-square wpc-default-status"></i>';
194 } else { // Quiz
195 $icon = '<i class="fa-solid fa-graduation-cap"></i>';
196 }
197 } else {
198 $icon = '<i class="fa-solid fa-lock wpc-default-status"></i>';
199 }
200 }
201
202 // Check for WooCommerce and Paid Memberships Pro restrictions
203 if(has_filter( 'wpc_lesson_button_icon' )){
204 $icon = apply_filters( 'wpc_lesson_button_icon', $icon, $post_id );
205 }
206
207 return $icon;
208 }
209
210 /**
211 * Return css classes to assign to lesson buttons to indicate certian lesson statuses
212 * @param int $user_id User ID
213 * @param int $post_id Lesson or quiz ID that's currently being looped through
214 * @param int $active_post_id The current post that's being viewed
215 * @return CSS class
216 */
217
218 function get_lesson_li_class($user_id, $post_id, $active_post_id = null){
219 $class = '';
220 if(is_user_logged_in()){
221
222 $status = wpc_get_lesson_status($user_id, $post_id);
223 $viewed = (int) $status['viewed'];
224 $completed = (int) $status['completed'];
225
226 if($status['completed'] === 1){
227 $class = 'wpc-nav-item-success';
228 } else if($status['viewed'] === 1){
229 $class = 'wpc-nav-item-highlight';
230 }
231
232 }
233
234 if((int) $post_id === $active_post_id){
235 $class = 'wpc-active-nav-item';
236 }
237
238 return $class;
239
240 }
241
242 /**
243 * Returns navigation list for specific course
244 * @param int $course_id The course ID for the lesson nav list you'd like to retrieve
245 * @param int $user_id User ID is passed to display appropriate lesson icons like fa-check, fa-eye, etc.
246 * @return Ul lesson navigation list for a specific course
247 */
248
249 function wpc_get_classic_lesson_navigation($course_id, $user_id = 0){
250 $html = '';
251 $count = 1;
252
253 $args = array(
254 'post_to' => $course_id,
255 'connection_type' => array('lesson-to-course', 'module-to-course', 'quiz-to-course'),
256 'order_by' => 'menu_order',
257 'order' => 'asc',
258 'join' => true,
259 'join_on' => "post_from"
260 );
261
262 $lessons = wpc_get_connected($args);
263
264 if(!empty($lessons)){
265 $html .= '<ul class="wpc-nav-list wpc-lesson-nav wpc-classic-lesson-nav wpc-transition-nav">';
266 $this_post_id = get_the_ID();
267
268 $modules_opened_option = get_option('wpc_modules_opened') === 'true';
269 $active_module_id = 0;
270
271 // Preliminary loop to find which module contains the current lesson
272 if (!$modules_opened_option) {
273 $temp_module_id = 0;
274 foreach ($lessons as $l) {
275 if ($l->connection_type == 'module-to-course') {
276 $temp_module_id = $l->post_from;
277 }
278 if ((int)$l->post_from === (int)$this_post_id) {
279 $active_module_id = $temp_module_id;
280 break;
281 }
282 }
283 }
284
285 $module_count = 0;
286
287 foreach($lessons as $lesson) {
288 $post_id = $lesson->post_from;
289 $restriction = get_post_meta( $post_id, 'wpc-lesson-restriction', true );
290
291 $icon = get_lesson_icon($user_id, $post_id, get_post_type($post_id));
292 $class = get_lesson_li_class($user_id, $post_id, $this_post_id);
293
294 $url = wpc_course_id_to_url(get_the_permalink($lesson->post_from), $course_id);
295
296 if($lesson->connection_type == 'module-to-course' && $lesson->post_status == 'publish'){
297 $html .= $module_count !== 0 ? '</div>' : '';
298
299 // Determine if this specific module should be open
300 $is_this_active_module = ($active_module_id != 0 && $lesson->post_from == $active_module_id);
301 $open = $modules_opened_option || $is_this_active_module;
302
303 $angle = $open ? 'fa fa-angle-down' : 'fa fa-angle-up';
304 $status = $open ? 'true' : 'false';
305 $style = $open ? '' : 'style="height: 0px;"';
306
307 $html .= '<li class="wpc-module-title wpc-nav-list-header" data-module-id="' . $module_count . '" data-status="'.$status.'"><i class="fa ' . $angle . '"></i> ' . get_the_title($lesson->post_from) . '</li>';
308 $html .= '<div class="wpc-nav-list-section" data-height="null" data-module-id="' . $module_count . '" data-status="'.$status.'" '.$style.'>';
309 $module_count++;
310 } elseif($lesson->connection_type == 'lesson-to-course' && $lesson->post_status == 'publish' || $lesson->connection_type == 'quiz-to-course' && $lesson->post_status == 'publish') {
311 $html .= '<li data-id="' . (int) $lesson->post_from . '"><a class="wpc-lesson-button lesson-button ' . $class . '" data-lesson-button-id="' . (int) $lesson->post_from . '" href="' . $url . '">' . $icon . get_the_title($lesson->post_from) . '</a></li>';
312 $count++;
313 }
314 }
315
316 // Close the last module div if one was opened
317 if ($module_count > 0) {
318 $html .= '</div>';
319 }
320
321 $html .= '</ul>';
322 wp_reset_postdata();
323 }
324
325 return $html;
326
327 }
328
329 /**
330 * Returns a multiselect dropdown for selecting courses
331 * @param array $selected_ids An array of selected courses ids so they can be selected on load
332 * @param string $name The name parameter value for the select
333 * @param string $class Class name assigned to select
334 * @return Course multiselect
335 */
336
337 function wpc_course_multiselect($selected_ids, $name = "course-selection[]", $class = 'wpc-course-multiselect') {
338 global $wpdb;
339 $sql = 'SELECT DISTINCT ID, post_title, post_status FROM '.$wpdb->posts.' WHERE post_type = "course" AND post_status = "publish" OR post_type = "course" AND post_status = "draft" ORDER By post_title';
340 $results = $wpdb->get_results($sql); ?>
341
342 <select name="<?php echo $name; ?>" class="<?php echo $class; ?>" multiple>
343 <option value="-1" <?php echo in_array(-1, $selected_ids) ? 'selected' :''; ?>>None</option>
344 <?php
345 foreach($results as $result) {
346 $selected = in_array($result->ID, $selected_ids) ? ' selected' : '';
347 echo '<option value="' . (int) $result->ID . '" ' . $selected . '>' . get_the_title((int) $result->ID) . '</option>';
348 }
349 ?>
350 </select>
351 <?php }
352
353 /**
354 * @param int $course_id Course ID for the lesson list you'd like to retrieve
355 * @return An ul of lessons, quizzes and modules for sorting and managing modules
356 */
357
358 function wpc_admin_lesson_list($course_id) {
359 $args = array(
360 'post_to' => $course_id,
361 'connection_type' => array('lesson-to-course', 'module-to-course', 'quiz-to-course'),
362 'order_by' => 'menu_order',
363 'order' => 'ASC',
364 'join' => true,
365 'join_on' => 'post_from',
366 );
367
368 $lessons = wpc_get_connected($args);
369
370 $html = '<ul class="wpc-nav-list wpc-nav-list-contained wpc-admin-lesson-list">';
371
372 if(!empty($lessons)) {
373
374 foreach($lessons as $lesson) {
375
376 if($lesson->post_type == 'wpc-module' ) {
377 $html .= '<li data-id="' . $lesson->post_from . '" data-post-type="' . $lesson->post_type . '" data-course-id="' . $course_id . '" class="wpc-order-lesson-list-lesson wpc-nav-list-header ui-sortable-handle wpc-module-button"><i class="fa-solid fa-grip"></i> <input class="wpc-input wpc-module-title-input" type="text" placeholder="Module Name" value="' . $lesson->post_title . '" class="wpc-module-title-input"><button type="button" class="wpc-delete-module wpc-btn wpc-btn-icon"><i class="fa fa-trash"></i></button></li>';
378 } else if($lesson->post_type == 'lesson' || $lesson->post_type == 'wpc-quiz') {
379 $html .= '<li data-id="' . $lesson->post_from . '" data-post-type="' . $lesson->post_type . '" data-course-id="' . $course_id . '" class="wpc-order-lesson-list-lesson"><i class="fa-solid fa-grip"></i> ' . $lesson->post_title . '<a style="float:right;" href="' . get_edit_post_link($lesson->post_from) . '"> Edit</a></li>';
380 }
381
382 }
383
384 }
385
386 $html .= '</ul>';
387
388 echo $html;
389 }
390
391 /**
392 * @param int $course_id Course ID for the option you'd like selected by default
393 * @param string $class Class you'd like to apply to the select dropdown
394 * @param bool $none Sets if the "none" option is available
395 * @param bool $name Sets the name parameter value for the select element
396 * @return string $name Name parameter value for the select
397 */
398
399 function wpc_get_course_dropdown($course_id = null, $class = 'wpc-select', $none = true, $name = 'course-selection'){
400
401 $course_id = (int) $course_id;
402 $name = sanitize_title_with_dashes($name);
403
404 global $wpdb;
405 $sql = 'SELECT DISTINCT ID, post_title, post_status FROM '.$wpdb->posts.' WHERE post_type = "course" AND post_status = "publish" OR post_type = "course" AND post_status = "draft" ORDER By post_title';
406 $results = $wpdb->get_results($sql);
407
408 $html = '';
409
410 $html .= '<select name="' . $name . '" class="' . $class . '">';
411 $html .= $none == true ? '<option value="-1">None</option>' : '';
412
413 foreach($results as $result) {
414 if($result->ID == $course_id){
415 $selected = 'selected';
416 } else {
417 $selected = '';
418 }
419 if(!empty($result->ID)){
420 $html .= '<option value="' . (int) $result->ID . '" ' . $selected . '>' . $result->post_title . '</option>';
421 }
422 }
423
424 $html .= '</select>';
425 return $html;
426
427 }
428
429 /**
430 * @param int $lesson_id Lesson ID for the breadcrumb trail you'd like to retrieve
431 * @param int $course_id The course ID for the breadcrumb trail you'd like to retrieve
432 * @return A breadcrumb trail
433 */
434
435 function wpc_get_breadcrumb($lesson_id, $course_id = null){
436 $show_breadcrumb = get_option('wpc_show_breadcrumb_trail');
437 $user_id = get_current_user_id();
438 $terms = get_the_terms($course_id, 'course-category');
439
440 if($show_breadcrumb != true || empty($terms) && $course_id == 'none'){
441 return;
442 }
443
444 $term_link = empty($terms) ? '' : '<a href="' . get_term_link($terms[0]->term_id) . '">' . $terms[0]->name . '</a> > ';
445 $course_link = $course_id != 'none' || $course_id != -1 ? '<a href="#" class="wpc-load-course" data-id="' . $course_id . '" data-ajax="false">' . get_the_title($course_id) . '</a> > ' : '';
446
447 $lesson_link = wpc_course_id_to_url(get_the_permalink($lesson_id), $course_id);
448
449 return '<div class="wpc-breadcrumb">' . $term_link . $course_link . '<a href="' . $lesson_link . '">' . get_the_title($lesson_id) . '</a></div>';
450 }
451
452 /**
453 * @param int $user_id The user ID for which you'd like to retrieve the tracking table for
454 * @param int $page Page number you'd like to get
455 * @param int $posts_per_page Number of table rows per table
456 * @param int $view 0 for viewed lessons, 1 for completed lessons
457 * @param bool $links false will return ajax links/buttons, true will return permalinks
458 * @return A table with viewed lesson data in order of most recently viewed
459 */
460
461 function wpc_get_lesson_tracking_table($user_id, $page = 1, $posts_per_page = -1, $view = 0, $ajax_links = false){
462
463 if($view == 0){
464 $text = esc_html__('Viewed', 'wp-courses');
465 $dataView = 'viewed';
466 } else {
467 $text = esc_html__('Completed', 'wp-courses');
468 $dataView = 'completed';
469 }
470
471 $html = '';
472
473 $tracked_lessons = wpc_get_tracked_lessons_by_user($user_id, $view, $page, $posts_per_page, false);
474
475 if(!empty($tracked_lessons)) {
476
477 $html .= '<table class="wpc-table wpc-lesson-table wpc-fade" cellspacing="0">';
478 $html .= '<thead>
479 <tr><th scope="col">' . esc_html__('Lesson Name', 'wp-courses') . '</th>
480 <th scope="col">' . esc_html__('Course Name', 'wp-courses') . '</th>
481 <th scope="col">' . esc_html__('Time', 'wp-courses') . ' ' . $text .'</th></tr></thead>';
482 $html .= '<tbody>';
483
484 foreach( $tracked_lessons as $viewed ){
485
486 $lesson_id = $viewed->post_id;
487
488 $html .= '<tr data-id="' . $lesson_id . '">';
489 $html .= '<td>';
490
491 $courses_shortcode_url = wpc_get_main_shortcode_page_url();
492 if ($courses_shortcode_url) {
493 $params = array(
494 'view' => 'single-lesson',
495 'course_id' => $viewed->course_id,
496 'lesson_id' => $lesson_id,
497 'page' => 'null',
498 'category' => 'null',
499 'orderby' => 'null',
500 'search' => 'null',
501 );
502 $courses_hash = wpc_get_courses_hash($params);
503 $link = $courses_shortcode_url . $courses_hash;
504 } else {
505 $link = add_query_arg( array('course_id' => $viewed->course_id ), get_the_permalink($lesson_id) );
506 }
507 $title = get_the_title($lesson_id);
508 $html .= '<a class="wpc-link" href="' . $link . '">' . $title . '</a>';
509
510 $html .= '</td>';
511
512 $html .= '<td>';
513
514 $html .= get_the_title( $viewed->course_id );
515
516 $html .= '</td>';
517
518 $html .= '<td>';
519 $html .= $view === 0 ? date('d/m/Y H:i', $viewed->viewed_timestamp) : date('d/m/Y H:i', $viewed->completed_timestamp);
520 $html .= '</td>';
521
522 $html .= '</tr>';
523
524 }
525
526 $html .= '<tbody>';
527 $html .= '</table>';
528
529 } else {
530 $html .= __('No results', 'wp-courses');
531 }
532
533 return $html;
534
535 }
536
537 /**
538 * @param int $user_id The user ID for which you'd like to retrieve the tracking table for
539 * @param array $args Arguments for WP_Query()
540 * @param bool $links True to get permalinks, false to get AJAX load css lasses
541 * @return A table with course completion data for a specific user
542 */
543
544 function wpc_get_course_progress_table($user_id, $args, $ajax_links = false){
545
546 $html = '';
547
548 $query = new WP_Query($args);
549
550 $html .= '<table class="wpc-table wpc-fade">';
551
552 $html .= '<thead>
553 <tr><th></th><th>' . esc_html__('Title', 'wp-courses') . '</th><th>' . esc_html__('Viewed', 'wp-courses') . '</th><th>' . esc_html__('Completed', 'wp-courses') . '</th></tr>
554 </thead>';
555
556 while($query->have_posts()){
557 $query->the_post();
558
559 $course_id = get_the_id();
560 $link = get_the_permalink($course_id);
561 $title = get_the_title($course_id);
562
563
564 $args = array(
565 'post_to' => $course_id,
566 'connection_type' => array('lesson-to-course', 'quiz-to-course'),
567 'order_by' => 'menu_order',
568 'order' => 'asc',
569 'join' => true,
570 'join_on' => "post_from"
571 );
572
573 $lessons_quizzes = wpc_get_connected($args);
574 $course_content = is_array($lessons_quizzes) ? count($lessons_quizzes) : 0;
575
576 if ($course_content) {
577 $html .= '<tr>';
578 $html .= '<td><button type="button" class="wpc-load-lesson-nav wpc-btn wpc-btn-sm wpc-open-modal wpc-btn-solid wpc-btn-round" data-id="' . $course_id . '" data-course-id="' . $course_id . '" data-selector=".wpc-lightbox-content" data-load-nav="true">' . esc_html( __('Details') ) . '</button></td>';
579 $html .= '<td>';
580
581 $courses_shortcode_url = wpc_get_main_shortcode_page_url();
582 $first_lesson_id = wpc_get_course_first_lesson_id($course_id);
583 if ($courses_shortcode_url) {
584 $params = array(
585 'view' => 'single-lesson',
586 'course_id' => $course_id,
587 'lesson_id' => $first_lesson_id,
588 'page' => 'null',
589 'category' => 'null',
590 'orderby' => 'null',
591 'search' => 'null',
592 );
593 $courses_hash = wpc_get_courses_hash($params);
594 $link = $courses_shortcode_url . $courses_hash;
595 }
596 $html .= '<a class="wpc-link" href="' . $link . '">' . $title . '</a>';
597
598 $html .= '</td>';
599 $html .= '<td>' . wpc_get_progress_bar($course_id, $user_id, false, false, 'rgb(79, 100, 109)') . '</td>';
600 $html .= '<td>' . wpc_get_progress_bar($course_id, $user_id, true, false) . '</td>';
601 $html .= '</tr>';
602 }
603
604 }
605
606 $html .= '</table>';
607
608 // $html .= $current_page; // Unassigned variable, needed anymore?
609
610 wp_reset_postdata();
611
612 return $html;
613 }
614
615 /**
616 * @param int $user_id The user ID for which you'd like to retrieve the results for
617 * @param array $args Arguments for WP_Query()
618 * @return A table with course completion data for a specific user
619 */
620
621 function wpc_get_award_results_table($user_id, $args){
622
623 ob_start();
624
625 echo '<div class="wpc-flex-container wpc-fade">';
626
627 $query = new WP_Query($args);
628
629 while($query->have_posts()){
630 $query->the_post();
631
632 $post_id = get_the_ID();
633
634 $has_requirement = wpc_has_requirement($post_id, $user_id);
635 $class = $has_requirement === true ? 'wpc-has-badge' : 'wpc-no-badge';
636
637 if($args['post_type'] === 'wpc-certificate') {
638 $award = wpc_render_tiny_certificate($user_id, $post_id);
639 } else {
640 $award = wpc_render_badge($post_id, $class, true);
641 }
642
643 if( wpc_has_requirement( $post_id, $user_id ) == true ){
644 $has = '<i class="fa-solid fa-circle-check wpc-correct-i"></i>';
645 } else {
646 $has = '<i class="fa-solid fa-circle-xmark wpc-incorrect-i"></i>';
647 }
648
649 echo '<div class="wpc-flex-3">' . $award . '</div>';
650
651 }
652
653 if (!$query->have_posts()) {
654 _e('No results', 'wp-courses');
655 }
656
657 echo '</div>';
658
659 wp_reset_postdata();
660
661 $ob_str = ob_get_contents();
662 ob_end_clean();
663
664 return $ob_str;
665
666 }
667
668 /**
669 * @return Returns a prompt that a certain feature is part of WP Courses Premium
670 */
671
672 function wpc_feature_upgrade_notice(){
673 return '<div id="wpc-feature-upgrade-notice"><p>This feature is only availabe with WP Courses Premium.</p><img src="' . WPC_PLUGIN_URL . 'images/premium.png"/><a class="wpc-btn" href="https://wpcoursesplugin.com/wp-courses-premium/">Learn More</a></div>';
674 }
675
676 /**
677 * @param string $percent Width of the progress indicator
678 * @param string $text The text inside the progress bar
679 * @param string $color Hex or RGB value for the progress bar's color
680 * @return A progress bar
681 */
682
683 function wpc_progress_bar($percent, $text = '', $color = '#4f646d'){
684
685 $html = '<div class="wpc-progress-wrapper"><div class="wpc-progress-inner" style="width: ' . $percent . '%; background-color: ' . $color . '" data-current-percent="' . $percent . '" data-percent="' . $percent . '"><div class="wpc-progress-text"><span class="wpc-progress-perecent">' . $percent . '</span>% ' . $text . '</div></div></div>';
686
687 return $html;
688
689 }
690
691 /**
692 * @param int $course_id
693 * @param int $user_id
694 * @param int $view 0 for viewed percent, 1 for completed percent
695 * @param bool $text Whether or not to show "Viewed" or "Completed" text inside the progress bar
696 * @param hex/rgb string $color The color of the progress bar
697 * @return A progress bar
698 */
699
700 function wpc_get_progress_bar($course_id, $user_id = null, $view = 1, $text = true, $color = '#4f646d') {
701 $course_id = (int) $course_id;
702
703 if($user_id == null){
704 $user_id = get_current_user_id();
705 }
706
707 if($view == 1){
708 $percent = wpc_get_percent_done($course_id, $user_id, 1);
709 $text = '';
710 $class = "wpc-complete-progress";
711 $icon = '<i class="fa fa-check"></i> ';
712 } else {
713 $percent = wpc_get_percent_done($course_id, $user_id, 0);
714 $text = $text == true ? esc_html__('Viewed', 'wp-courses') : '';
715 $class = "wpc-viewed-progress wpc-hide-viewed";
716 $icon = '<i class="fa-solid fa-eye"></i> ';
717 }
718
719 $data = '<div class="wpc-progress-wrapper"><div class="wpc-progress-inner ' . $class . '" style="width: ' . $percent . '%; background-color: ' . $color . '" data-current-percent="' . $percent . '" data-percent="' . $percent . '"><div class="wpc-progress-text"><span class="wpc-progress-perecent">' . $percent . '</span>% ' . $text . '</div></div></div>';
720
721 return $data;
722 }
723
724 /**
725 * @param int $lesson_id The ID for the lesson that has attachments you'd like to retrieve
726 * @return array An array with attachment URLs
727 */
728
729 function wpc_get_lesson_attachments($lesson_id){
730
731 $attachments = array();
732 for($i = 1; $i<=3; $i++){
733 $url = get_post_meta( $lesson_id, 'wpc-media-sections-' . $i, true );
734 if(!empty($url)){
735 $url = esc_url( $url );
736 array_push($attachments, $url);
737 }
738
739 }
740
741 return $attachments;
742 }
743
744 function wpc_get_comments($post_id){
745 $comments = get_comments(array(
746 'post_id' => $post_id,
747 'status' => 'approve',
748 ));
749
750 $html = count($comments) > 0 ? '<h2 class="wpc-comments-header wpc-h2">Comments</h3>' : '';
751
752 $html .= '<ul class="wpc-comments">';
753 foreach($comments as $comment) {
754 $avatar = get_avatar($comment->user_id, 32);
755 $html .= '<li class="wpc-comment"><div class="wpc-comment-avatar">' . $avatar . '</div><div class="wpc-comment-author">' . $comment->comment_author . '</div><div class="wpc-comment-date">' . $comment->comment_date . '</div><div class="wpc-comment-content">' . $comment->comment_content . '</div></li>';
756 }
757 $html .= '</ul>';
758
759 return $html;
760
761 }
762
763 function wpc_get_comments_template($post_id){
764
765 $html = '';
766
767 $logged_in = is_user_logged_in();
768
769 $require_name_email = get_option('require_name_email');
770 $comment_registration = get_option('comment_registration');
771
772 $login_url = wp_login_url();
773 $registration_url = wp_registration_url();
774
775 $comments_open = comments_open($post_id);
776
777 if($comments_open === true) {
778
779 $html .= '<h2 class="wpc-comments-header wpc-h2">' . __('Leave a Comment', 'wp-courses') . '</h3>';
780
781 if($logged_in == false && $comment_registration == 1) {
782 $html .= '<div class="wpc-comments-register-login wpc-alert-message"><a href="' . $login_url . '">' . __('Login', 'wp-courses') . '</a> ' . __('or', 'wp-courses') . ' <a href="' . $registration_url . '">' . __('Register', 'wp-courses') . '</a> ' . __('to leave a comment.', 'wp-courses') . '</div>';
783 } else {
784 $html .= '<textarea id="wpc-comment-textarea"></textarea>';
785 $html .= '<div class="wpc-flex-container" style="margin: 2% -1% 0;">';
786 $html .= $require_name_email == 1 ? '<div class="wpc-flex-4"><input id="wpc-comment-name" class="wpc-input" type="text" placeholder="' . __('Name', 'wp-courses') . '"/></div>' : '';
787 $html .= $require_name_email == 1 ? '<div class="wpc-flex-4"><input id="wpc-comment-email" class="wpc-input" type="email" placeholder="' . __('Email Address', 'wp-courses') . '"/></div>' : '';
788 $html .= '<div class="wpc-flex-4"><input id="wpc-comment-url" class="wpc-input" type="url" placeholder="' . __('Website', 'wp-courses') . '"/></div>';
789 $html .= '</div>';
790 $html .= '<button id="wpc-submit-comment" class="wpc-btn" data-id="' . $post_id . '">' . __('Post Comment', 'wp-courses') . '</button>';
791 }
792
793 $html .= wpc_get_comments($post_id);
794
795 }
796
797 return $html;
798
799 }
800
801 /**
802 * Returns a list of lesson names, connected to a specific course
803 * @param array $lessons_quizzes An array of lessons and quizzes
804 * @return string ordered list
805 */
806
807 function wpc_lesson_collection($lessons) {
808 if (!empty($lessons)) {
809 ?> <ol class="wpc-connected-courses-list"> <?php
810 foreach($lessons as $lq) {
811 $title = $lq->post_title;
812 $title = strlen($title) > 18 ? substr($title, 0, 15) . '...' : $title;
813
814 echo '<li>' . $title . '</li>';
815 }
816 ?> </ol> <?php
817 } else {
818 echo '';
819 }
820 }
821
822 /**
823 * Returns a list of lesson names, connected to a specific course
824 * @param array $teachers An array of lessons and quizzes
825 * @return string ordered list
826 */
827
828 function wpc_teacher_collection($teachers) {
829 if (!empty($teachers) && $teachers[0]->post_title) {
830 ?> <ol class="wpc-connected-courses-list"> <?php
831 foreach($teachers as $t) {
832 $title = $t->post_title;
833 $title = strlen($title) > 18 ? substr($title, 0, 15) . '...' : $title;
834
835 echo '<li>' . $title . '</li>';
836 }
837 ?> </ol> <?php
838 } else {
839 echo '';
840 }
841 }
842
843 function wpc_course_collection($courses) {
844 if (!empty($courses) && $courses[0]->post_title) {
845 ?> <ol class="wpc-connected-courses-list"> <?php
846 foreach($courses as $t) {
847 $title = $t->post_title;
848 $title = strlen($title) > 18 ? substr($title, 0, 15) . '...' : $title;
849
850 echo '<li>' . $title . '</li>';
851 }
852 ?> </ol> <?php
853 } else {
854 echo '';
855 }
856 }