PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.6.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.6.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 4.2.0 All 139 releases
learnpress / inc / lp-core-functions.php

lp-core-functions.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.6.9, at inc/lp-core-functions.php

3,872 lines 96.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * LearnPress Core Functions
4 * Define common functions for both front-end and back-end
5 *
6 * @author ThimPress
7 * @package LearnPress/Functions
8 * @version 1.0
9 */
10
11 defined( 'ABSPATH' ) || exit;
12
13 function learnpress_gutenberg_disable_cpt( $can_edit, $post_type ) {
14 $post_types = array(
15 LP_COURSE_CPT => LP_Settings::get_option( 'enable_gutenberg_course', 'no' ),
16 LP_LESSON_CPT => LP_Settings::get_option( 'enable_gutenberg_lesson', 'no' ),
17 LP_QUIZ_CPT => LP_Settings::get_option( 'enable_gutenberg_quiz', 'no' ),
18 LP_QUESTION_CPT => LP_Settings::get_option( 'enable_gutenberg_question', 'no' ),
19 );
20
21 foreach ( $post_types as $key => $pt ) {
22 if ( $post_type === $key && $pt !== 'yes' ) {
23 $can_edit = false;
24 }
25 }
26
27 return $can_edit;
28 }
29 add_filter( 'use_block_editor_for_post_type', 'learnpress_gutenberg_disable_cpt', 10, 2 );
30
31 /**
32 * Get instance of a CURD class by type
33 *
34 * @param string $type
35 *
36 * @return bool|LP_Course_CURD|LP_User_CURD|LP_Quiz_CURD|LP_Question_CURD
37 */
38 function learn_press_get_curd( $type ) {
39 $curds = array(
40 'user' => 'LP_User_CURD',
41 'course' => 'LP_Course_CURD',
42 'quiz' => 'LP_Quiz_CURD',
43 'question' => 'LP_Question_CURD',
44 );
45
46 $curd = false;
47
48 if ( ! empty( $curds[ $type ] ) && class_exists( $curds[ $type ] ) ) {
49 $curd = new $curds[ $type ]();
50 }
51
52 return apply_filters( 'learn-press/curd', $curd, $type, $curds );
53 }
54
55 if ( ! function_exists( 'lp_add_body_class' ) ) {
56 function lp_add_body_class( $classes ) {
57 $classes = (array) $classes;
58
59 if ( learn_press_is_profile() ) {
60 $classes[] = 'learnpress-profile';
61 } elseif ( learn_press_is_checkout() ) {
62 $classes[] = 'learnpress-checkout';
63 }
64
65 return $classes;
66 }
67 add_filter( 'body_class', 'lp_add_body_class' );
68 }
69
70 /**
71 * Short function to get name of a theme
72 *
73 * @param string $folder
74 *
75 * @return mixed|string
76 */
77 function learn_press_get_theme_name( $folder ) {
78 $theme = wp_get_theme( $folder );
79
80 return ! empty( $theme['Name'] ) ? $theme['Name'] : '';
81 }
82
83 /**
84 * Clean.
85 *
86 * @param [type] $var
87 *
88 * @version 4.0.0
89 * @author Nhamdv <daonham95@gmail.com>
90 */
91 function learnpress_clean( $var ) {
92 if ( is_array( $var ) ) {
93 return array_map( 'learnpress_clean', $var );
94 } else {
95 return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
96 }
97 }
98
99 /**
100 * Display HTML of element for building QuickTip JS.
101 *
102 * @param string $tip
103 * @param bool $echo
104 * @param array $options
105 *
106 * @return string
107 * @since 3.0.0
108 */
109 function learn_press_quick_tip( $tip, $echo = true, $options = array() ) {
110 $atts = '';
111 if ( $options ) {
112 foreach ( $options as $k => $v ) {
113 $options[ $k ] = "data-{$k}=\"{$v}\"";
114 }
115 $atts = ' ' . implode( ' ', $options );
116 }
117
118 $tip = sprintf( '<span class="learn-press-tip" ' . $atts . '>%s</span>', $tip );
119
120 if ( $echo ) {
121 echo wp_kses_post( $tip );
122 }
123
124 return $tip;
125 }
126
127 /**
128 * Return TRUE if defined WP_DEBUG and is true or 1.
129 *
130 * @return bool
131 * @editor tungnx
132 * @depecated 4.1.6.4
133 */
134 function learn_press_is_debug() {
135 _deprecated_function( __FUNCTION__, '4.1.6.4' );
136 return LP_Debug::is_debug();
137 }
138
139 /**
140 * Get current post ID.
141 *
142 * @return int
143 */
144 function learn_press_get_post() {
145 global $post;
146
147 $post_id = learn_press_get_request( 'post' );
148
149 if ( ! $post_id ) {
150 $post_id = ! empty( $post ) ? $post->ID : 0;
151 }
152 if ( empty( $post_id ) ) {
153 $post_id = learn_press_get_request( 'post_ID' );
154 }
155
156 return absint( $post_id );
157 }
158
159 /**
160 * Get the LearnPress plugin url
161 *
162 * @param string $sub_dir
163 *
164 * @return string
165 */
166 function learn_press_plugin_url( $sub_dir = '' ) {
167 return LP()->plugin_url( $sub_dir );
168 }
169
170 /**
171 * Get the LearnPress plugin path.
172 *
173 * @param string $sub_dir
174 *
175 * @return string
176 */
177 function learn_press_plugin_path( $sub_dir = '' ) {
178 return LP()->plugin_path( $sub_dir );
179 }
180
181 /**
182 * Includes file base on LearnPress path
183 *
184 * @param string $file
185 * @param string $folder
186 * @param bool $include_once
187 *
188 * @return bool
189 */
190 function learn_press_include( $file, $folder = 'inc', $include_once = true ) {
191 $include = learn_press_plugin_path( "{$folder}/{$file}" );
192
193 if ( file_exists( $include ) ) {
194 if ( $include_once ) {
195 include_once $include;
196 } else {
197 include $include;
198 }
199
200 return true;
201 }
202
203 return false;
204 }
205
206 /**
207 * Get current IP of the user
208 *
209 * @return mixed
210 */
211 function learn_press_get_ip() {
212 if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
213 return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) );
214 } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
215 // Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
216 // Make sure we always only send through the first IP in the list which should always be the client IP.
217 return (string) rest_is_ip_address( trim( current( preg_split( '/,/', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) );
218 } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
219 return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
220 }
221 return '';
222 }
223
224 /**
225 * Get user agent.
226 *
227 * @return string
228 */
229 function learn_press_get_user_agent(): string {
230 return LP_Helper::sanitize_params_submitted( $_SERVER['HTTP_USER_AGENT'] ?? '' );
231 }
232
233 /**
234 * Generate an unique string.
235 *
236 * @param string $prefix
237 *
238 * @return string
239 */
240 function learn_press_uniqid( $prefix = '' ) {
241 $hash = str_replace( '.', '', microtime( true ) . uniqid() );
242
243 return apply_filters( 'learn-press/generate-hash', $prefix . $hash, $prefix );
244 }
245
246 function learn_press_random_value( $len = 8 ) {
247 return substr( md5( uniqid( mt_rand(), true ) ), 0, $len );
248 }
249
250 function learn_press_map_columns_format( $columns, $format ) {
251 $return = array();
252 foreach ( $columns as $k => $v ) {
253 if ( ! empty( $format[ $k ] ) ) {
254 $return[] = $format[ $k ];
255 } else {
256 $return[] = '%s'; // default is string
257 }
258 }
259
260 return $return;
261 }
262
263 /**
264 * Check to see if an endpoint is showing in current URL.
265 *
266 * @param bool $endpoint
267 *
268 * @return bool
269 */
270 function learn_press_is_endpoint_url( $endpoint = false ) {
271 global $wp;
272
273 $endpoints = array();
274
275 if ( $endpoint !== false ) {
276 if ( ! isset( $endpoints[ $endpoint ] ) ) {
277 return false;
278 } else {
279 $endpoint_var = $endpoints[ $endpoint ];
280 }
281
282 return isset( $wp->query_vars[ $endpoint_var ] );
283 } else {
284 foreach ( $endpoints as $key => $value ) {
285 if ( isset( $wp->query_vars[ $key ] ) ) {
286 return true;
287 }
288 }
289
290 return false;
291 }
292 }
293
294 /**
295 * Get current URL user is viewing.
296 *
297 * @return string
298 */
299 function learn_press_get_current_url() {
300 static $current_url;
301
302 if ( ! $current_url ) {
303 $url = untrailingslashit( esc_url_raw( $_SERVER['REQUEST_URI'] ) );
304
305 if ( ! preg_match( '!^https?!', $url ) ) {
306 $siteurl = trailingslashit( get_home_url() );
307 $home_query = '';
308
309 if ( strpos( $siteurl, '?' ) !== false ) {
310 $parts = explode( '?', $siteurl );
311 $home_query = $parts[1];
312 $siteurl = $parts[0];
313 }
314
315 if ( $home_query ) {
316 parse_str( untrailingslashit( $home_query ), $home_query );
317 $url = esc_url_raw( add_query_arg( $home_query, $url ) );
318 }
319
320 $segs1 = explode( '/', $siteurl );
321 $segs2 = explode( '/', $url );
322
323 if ( $removed = array_intersect( $segs1, $segs2 ) ) {
324 if ( $segs2 = array_diff( $segs2, $removed ) ) {
325 $current_url = $siteurl . join( '/', $segs2 );
326 if ( strpos( $current_url, '?' ) === false ) {
327 $current_url = trailingslashit( $current_url );
328 }
329 }
330 }
331 }
332 }
333
334 return $current_url;
335 }
336
337 /**
338 * Compares an url with current URL user is viewing
339 *
340 * @param string $url
341 *
342 * @return bool
343 */
344 function learn_press_is_current_url( $url ) {
345 $current_url = learn_press_get_current_url();
346
347 return ( $current_url && $url ) && strcmp( $current_url, learn_press_sanitize_url( $url ) ) == 0;
348 }
349
350 /**
351 * Remove unneeded characters in an URL
352 *
353 * @param string $url
354 * @param bool $trailingslashit
355 *
356 * @return string
357 */
358 function learn_press_sanitize_url( $url, $trailingslashit = true ) {
359 if ( $url ) {
360 preg_match( '!(https?://)?(.*)!', $url, $matches );
361 $url_without_http = $matches[2];
362 $url_without_http = preg_replace( '![/]+!', '/', $url_without_http );
363 $url = $matches[1] . $url_without_http;
364
365 return ( $trailingslashit &&
366 strpos( $url, '?' ) === false ) ? trailingslashit( $url ) : untrailingslashit( $url );
367 }
368
369 return $url;
370 }
371
372 /**
373 * Get all types of question supported
374 *
375 * @return mixed
376 */
377 function learn_press_question_types() {
378 return LP_Question::get_types();
379 }
380
381 /**
382 * Get human name of question's type by slug
383 *
384 * @param string $slug
385 *
386 * @return array
387 */
388 function learn_press_question_name_from_slug( $slug ) {
389 $types = learn_press_question_types();
390 $name = ! empty( $types[ $slug ] ) ? $types[ $slug ] : '';
391
392 return apply_filters( 'learn-press/question/slug-to-name', $name, $slug );
393 }
394
395 /**
396 * Get the post types which supported to insert into course's section
397 *
398 * @return array
399 */
400 function learn_press_section_item_types() {
401 $types = array(
402 'lp_lesson' => esc_html__( 'Lesson', 'learnpress' ),
403 'lp_quiz' => esc_html__( 'Quiz', 'learnpress' ),
404 );
405
406 return apply_filters( 'learn-press/section/support-item-type', $types );
407 }
408
409 /**
410 * Enqueue js code to print out
411 *
412 * @param string $code
413 * @param bool $script_tag - wrap code between <script> tag
414 * @depecated 4.1.6.8
415 */
416 function learn_press_enqueue_script( $code, $script_tag = false ) {
417 _deprecated_function( __FUNCTION__, '4.1.6.8' );
418 global $learn_press_queued_js, $learn_press_queued_js_tag;
419
420 if ( $script_tag ) {
421 if ( empty( $learn_press_queued_js_tag ) ) {
422 $learn_press_queued_js_tag = '';
423 }
424 $learn_press_queued_js_tag .= "\n" . $code . "\n";
425 } else {
426 if ( empty( $learn_press_queued_js ) ) {
427 $learn_press_queued_js = '';
428 }
429
430 $learn_press_queued_js .= "\n" . $code . "\n";
431 }
432 }
433
434 /**
435 * Get terms of a course by taxonomy.
436 * E.g: course_tag, course_category
437 *
438 * @param int $course_id
439 * @param string $taxonomy
440 * @param array $args
441 *
442 * @return array|mixed
443 */
444 function learn_press_get_course_terms( $course_id, $taxonomy, $args = array() ) {
445 if ( ! taxonomy_exists( $taxonomy ) ) {
446 return array();
447 }
448
449 // Support ordering by parent
450 if ( ! empty( $args['orderby'] ) && in_array( $args['orderby'], array( 'name_num', 'parent' ) ) ) {
451 $fields = isset( $args['fields'] ) ? $args['fields'] : 'all';
452 $orderby = $args['orderby'];
453
454 // Unset for wp_get_post_terms
455 unset( $args['orderby'] );
456 unset( $args['fields'] );
457
458 $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
459
460 switch ( $orderby ) {
461 case 'name_num':
462 usort( $terms, '_learn_press_get_course_terms_name_num_usort_callback' );
463 break;
464 case 'parent':
465 usort( $terms, '_learn_press_get_course_terms_parent_usort_callback' );
466 break;
467 }
468
469 switch ( $fields ) {
470 case 'names':
471 $terms = wp_list_pluck( $terms, 'name' );
472 break;
473 case 'ids':
474 $terms = wp_list_pluck( $terms, 'term_id' );
475 break;
476 case 'slugs':
477 $terms = wp_list_pluck( $terms, 'slug' );
478 break;
479 }
480 } elseif ( ! empty( $args['orderby'] ) && $args['orderby'] === 'menu_order' ) {
481 // wp_get_post_terms doesn't let us use custom sort order
482 $args['include'] = wp_get_post_terms( $course_id, $taxonomy, array( 'fields' => 'ids' ) );
483
484 if ( empty( $args['include'] ) ) {
485 $terms = array();
486 } else {
487 // This isn't needed for get_terms
488 unset( $args['orderby'] );
489
490 // Set args for get_terms
491 $args['menu_order'] = isset( $args['order'] ) ? $args['order'] : 'ASC';
492 $args['hide_empty'] = isset( $args['hide_empty'] ) ? $args['hide_empty'] : 0;
493 $args['fields'] = isset( $args['fields'] ) ? $args['fields'] : 'names';
494
495 // Ensure slugs is valid for get_terms - slugs isn't supported
496 $args['fields'] = $args['fields'] === 'slugs' ? 'id=>slug' : $args['fields'];
497 $terms = get_terms( $taxonomy, $args );
498 }
499 } else {
500 $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
501 }
502
503 // @deprecated
504 $terms = apply_filters( 'learn_press_get_course_terms', $terms, $course_id, $taxonomy, $args );
505
506 return apply_filters( 'learn-press/course/terms', $terms, $course_id, $taxonomy, $args );
507 }
508
509 /**
510 * Callback function for sorting terms of course by name.
511 *
512 * @param object $a
513 * @param object $b
514 *
515 * @return int
516 */
517 function _learn_press_get_course_terms_name_num_usort_callback( $a, $b ) {
518 if ( $a->name + 0 === $b->name + 0 ) {
519 return 0;
520 }
521
522 return ( $a->name + 0 < $b->name + 0 ) ? - 1 : 1;
523 }
524
525 /**
526 * Callback function for sorting terms of course by parent.
527 *
528 * @param object $a
529 * @param object $b
530 *
531 * @return int
532 */
533 function _learn_press_get_course_terms_parent_usort_callback( $a, $b ) {
534 if ( $a->parent === $b->parent ) {
535 return 0;
536 }
537
538 return ( $a->parent < $b->parent ) ? 1 : - 1;
539 }
540
541 /**
542 * Get posts by it's post-name (slug).
543 *
544 * @param string $name
545 * @param string $type
546 * @param bool $single
547 *
548 * @return array|bool|null|WP_Post
549 */
550 function learn_press_get_post_by_name( $name, $type, $single = true ) {
551 $post_name = sanitize_title( $name );
552 $id = LP_Object_Cache::get( $type . '-' . $post_name, 'learn-press/post-names' );
553
554 if ( false === $id ) {
555 foreach ( array( $name, urldecode( $name ) ) as $_name ) {
556 $args = array(
557 'name' => $_name,
558 'post_type' => array( $type ),
559 );
560
561 $posts = get_posts( $args );
562
563 if ( $posts ) {
564 $post = $posts[0];
565 $id = $post->ID;
566 wp_cache_set( $id, $post, 'posts' );
567 LP_Object_Cache::set( $type . '-' . $name, $id, 'learn-press/post-names' );
568 break;
569 }
570 }
571 }
572
573 return $id ? get_post( $id ) : false;
574 }
575
576 /**
577 * Cache static pages
578 *
579 * @deprecated 4.1.6.8
580 */
581 /*function learn_press_setup_pages() {
582 global $wpdb;
583
584 $page_ids = LP_Object_Cache::get( 'static-page-ids', 'learn-press' );
585
586 if ( false === $page_ids ) {
587 $pages = learn_press_static_pages( true );
588 $page_ids = array();
589
590 foreach ( $pages as $page ) {
591 $id = get_option( 'learn_press_' . $page . '_page_id' );
592
593 if ( absint( $id ) > 0 ) {
594 $page_ids[] = $id;
595 }
596 }
597
598 if ( ! $page_ids ) {
599 return;
600 }
601
602 $query = $wpdb->prepare(
603 "
604 SELECT ID, post_title, post_name, post_date, post_date_gmt, post_modified, post_modified_gmt, post_content, post_parent, post_type
605 FROM {$wpdb->posts}
606 WHERE %d AND ID IN(" . join( ',', $page_ids ) . ')
607 AND post_status <> %s
608 ',
609 1,
610 'trash'
611 );
612
613 if ( ! $rows = $wpdb->get_results( $query ) ) {
614 return;
615 }
616
617 foreach ( $rows as $page ) {
618 $page = sanitize_post( $page, 'raw' );
619 wp_cache_add( $page->ID, $page, 'posts' );
620 }
621 }
622 }*/
623
624 function learn_press_get_course_item_object( $post_type ) {
625 switch ( $post_type ) {
626 case 'lp_quiz':
627 $class = 'LP_Quiz';
628 break;
629 case 'lp_lesson':
630 $class = 'LP_Lesson';
631 break;
632 case 'lp_question':
633 $class = 'LP_Question';
634 }
635 }
636
637 /**
638 * Print out js code in the queue
639 *
640 * @depecated 4.1.6.8
641 */
642 function learn_press_print_script() {
643 _deprecated_function( __FUNCTION__, '4.1.6.8' );
644 global $learn_press_queued_js, $learn_press_queued_js_tag;
645
646 if ( ! empty( $learn_press_queued_js ) ) {
647 ?>
648 <!-- LearnPress JavaScript -->
649 <script type="text/javascript">
650 jQuery(function ($) {
651 <?php
652 $learn_press_queued_js = wp_check_invalid_utf8( $learn_press_queued_js );
653 $learn_press_queued_js = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", $learn_press_queued_js );
654 $learn_press_queued_js = str_replace( "\r", '', $learn_press_queued_js );
655
656 // echo $learn_press_queued_js;
657 ?>
658 })
659 </script>
660
661 <?php
662 unset( $learn_press_queued_js );
663 }
664
665 if ( ! empty( $learn_press_queued_js_tag ) ) {
666 // echo $learn_press_queued_js_tag;
667 }
668 }
669
670 // add_action( 'wp_footer', 'learn_press_print_script' );
671 // add_action( 'admin_footer', 'learn_press_print_script' );
672
673
674 /**
675 * @param string $str
676 * @param int $lines
677 * @depecated 4.1.6.8
678 */
679 /*function learn_press_email_new_line( $lines = 1, $str = "\r\n" ) {
680 echo str_repeat( $str, $lines );
681 }*/
682
683 if ( ! function_exists( 'learn_press_is_ajax' ) ) {
684 function learn_press_is_ajax() {
685 return defined( 'LP_DOING_AJAX' ) && LP_DOING_AJAX && 'yes' != learn_press_get_request( 'noajax' );
686 }
687 }
688
689 /**
690 * Get page id from admin settings page
691 *
692 * @param string $name
693 *
694 * @return int
695 */
696 function learn_press_get_page_id( string $name ): int {
697 $page_id = LP_Settings::instance()->get( "{$name}_page_id", false );
698
699 if ( function_exists( 'icl_object_id' ) ) {
700 $page_id = icl_object_id( $page_id, 'page', false, defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : '' );
701 }
702
703 $page_id = (int) $page_id;
704
705 return apply_filters( 'learn_press_get_page_id', $page_id, $name );
706 }
707
708 /**
709 * display the seconds in time format h:i:s
710 *
711 * @param $seconds
712 * @param string $separator
713 *
714 * @return string
715 */
716 function learn_press_seconds_to_time( $seconds, $separator = ':' ) {
717 return sprintf(
718 '%02d%s%02d%s%02d',
719 floor( $seconds / 3600 ),
720 $separator,
721 ( $seconds / 60 ) % 60,
722 $separator,
723 $seconds % 60
724 );
725 }
726
727 /* nav */
728 if ( ! function_exists( 'learn_press_course_paging_nav' ) ) {
729
730 /**
731 * Display navigation to next/previous set of posts when applicable.
732 *
733 * @param array
734 */
735 function learn_press_course_paging_nav( $args = array() ) {
736 learn_press_paging_nav(
737 array(
738 'num_pages' => $GLOBALS['wp_query']->max_num_pages,
739 'wrapper_class' => 'navigation pagination',
740 )
741 );
742 }
743 }
744
745 /* nav */
746 if ( ! function_exists( 'learn_press_paging_nav' ) ) {
747 function learn_press_paging_nav( $args = array() ) {
748 $args = wp_parse_args(
749 $args,
750 array(
751 'num_pages' => 0,
752 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
753 'wrapper_class' => 'learn-press-pagination',
754 'base' => false,
755 'format' => '',
756 'echo' => true,
757 )
758 );
759
760 if ( $args['num_pages'] < 2 ) {
761 return false;
762 }
763
764 $paged = $args['paged'];
765 $pagenum_link = html_entity_decode( $args['base'] === false ? get_pagenum_link() : $args['base'] );
766
767 $query_args = array();
768 $url_parts = explode( '?', $pagenum_link );
769
770 if ( isset( $url_parts[1] ) ) {
771 wp_parse_str( $url_parts[1], $query_args );
772 }
773
774 $pagenum_link = esc_url_raw( remove_query_arg( array_keys( $query_args ), $pagenum_link ) );
775 $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
776
777 $format = $GLOBALS['wp_rewrite']->using_index_permalinks() && ! strpos(
778 $pagenum_link,
779 'index.php'
780 ) ? 'index.php/' : '';
781 $format .= $args['format'] ? $args['format'] : ( $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit(
782 'page/%#%',
783 'paged'
784 ) : '?paged=%#%' );
785
786 $link_args = array(
787 'base' => $pagenum_link,
788 'format' => $format,
789 'total' => $args['num_pages'],
790 'current' => max( 1, $paged ),
791 'mid_size' => 1,
792 'add_args' => array_map( 'urlencode', $query_args ),
793 'prev_text' => __( '<', 'learnpress' ),
794 'next_text' => __( '>', 'learnpress' ),
795 'type' => 'list',
796 );
797
798 // Set up paginated links.
799 $links = paginate_links( $link_args );
800
801 ob_start();
802
803 if ( $links ) {
804 ?>
805 <div class="<?php echo esc_attr( $args['wrapper_class'] ); ?>">
806 <?php echo wp_kses_post( $links ); ?>
807 </div>
808 <?php
809 }
810
811 $output = ob_get_clean();
812
813 if ( $args['echo'] ) {
814 echo wp_kses_post( $output );
815 }
816
817 return $output;
818 }
819 }
820
821 /**
822 * Get number of pages by rows and items per page.
823 *
824 * @param int $total
825 * @param int $limit
826 *
827 * @return int
828 */
829 function learn_press_get_num_pages( $total, $limit = 10 ) {
830 $limit = $limit <= 0 ? 10 : $limit;
831
832 if ( $total <= $limit ) {
833 return 1;
834 }
835
836 $pages = absint( $total / $limit );
837
838 if ( $total % $limit != 0 ) {
839 $pages ++;
840 }
841
842 return $pages;
843 }
844
845 /**
846 * Get text
847 *
848 * @param $status_id
849 *
850 * @return mixed
851 */
852 function learn_press_get_status_text( $status_id ) {
853 switch ( $status_id ) {
854 case 1:
855 $text = 'pending';
856 break;
857 case 2:
858 $text = 'complete';
859 break;
860 case - 1:
861 $text = 'cancel';
862 break;
863 case - 2:
864 $text = 'refund';
865 break;
866 default:
867 $text = 'on-hold';
868 }
869
870 return $text;
871 }
872
873 function learn_press_get_course_duration_support() {
874 return apply_filters(
875 'learn_press_course_duration_support',
876 array(
877 'minute' => esc_html__( 'Minute(s)', 'learnpress' ),
878 'hour' => esc_html__( 'Hour(s)', 'learnpress' ),
879 'day' => esc_html__( 'Day(s)', 'learnpress' ),
880 'week' => esc_html__( 'Week(s)', 'learnpress' ),
881 )
882 );
883 }
884
885 function learn_press_number_to_string_time( $number ) {
886 $str = $number;
887
888 if ( preg_match( '!([0-9.]+) (minute|hour|day|week)!', $number, $matches ) ) {
889 switch ( $matches[2] ) {
890 case 'hour':
891 $minute = $matches[1] * 60;
892 $str = sprintf( '%s hour %s minute', absint( $minute / 60 ), $minute % 60 );
893 break;
894 case 'day':
895 $hour = $matches[1] * 24;
896 $str = sprintf( '%s day %s hour', absint( $hour / 24 ), $hour % 24 );
897 break;
898 case 'week':
899 $day = $matches[1] * 7;
900 $str = sprintf( '%s week %s day', absint( $day / 7 ), $day % 7 );
901 break;
902 }
903 }
904
905 return $str;
906 }
907
908 function learn_press_human_time_to_seconds( $time, $default = '' ) {
909 $duration = learn_press_get_course_duration_support();
910 $duration_keys = array_keys( $duration );
911
912 if ( preg_match_all( '!([0-9]+)\s*(' . join( '|', $duration_keys ) . ')?!', $time, $matches ) ) {
913 $a1 = $matches[1][0];
914 $a2 = in_array( $matches[2][0], $duration_keys ) ? $matches[2][0] : '';
915 } else {
916 $a1 = absint( $time );
917 $a2 = '';
918 }
919
920 if ( $a2 ) {
921 $b = array(
922 'minute' => 60,
923 'hour' => 3600,
924 'day' => 3600 * 24,
925 'week' => 3600 * 24 * 7,
926 );
927 $a1 = $a1 * $b[ $a2 ];
928 }
929
930 return $a1;
931 }
932
933 /**
934 * Send email notification.
935 *
936 * @param string $to .
937 * @param string $action .
938 * @param array $vars .
939 *
940 * @return bool
941 */
942 function learn_press_send_mail( $to = '', $action = '', $vars = array() ) {
943 $email_settings = LP_Settings::instance();
944
945 if ( ! $email_settings->get( $action . '.enable' ) ) {
946 return "The action {$action} doesnt support";
947 }
948
949 $user = get_user_by( 'email', $to );
950
951 $vars['log_in'] = apply_filters( 'learn_press_site_url', get_home_url() );
952
953 // Send email.
954 $email = new LP_Email();
955 $email->set_action( $action );
956 $email->parse_email( $vars );
957 $email->add_recipient( $to );
958
959 return $email->send();
960 }
961
962 /*
963 * Send email notification when a course be published
964 */
965 function learn_press_publish_course( $new_status, $old_status, $post ) {
966 if ( $old_status == 'pending' && $new_status == 'publish' && $post->post_type == 'lp_course' ) {
967 $instructor = get_userdata( $post->post_author );
968 $mail_to = $instructor->user_email;
969
970 learn_press_send_mail(
971 $mail_to,
972 'published_course',
973 apply_filters(
974 'learn_press_vars_enrolled_course',
975 array(
976 'user_name' => $instructor->display_name,
977 'course_name' => $post->post_title,
978 'course_link' => get_permalink( $post->ID ),
979 ),
980 $post,
981 $instructor
982 )
983 );
984 }
985 }
986
987 add_action( 'transition_post_status', 'learn_press_publish_course', 10, 3 );
988
989 /**
990 * @param $user_id
991 *
992 * @return WP_Query
993 * @depecated 4.1.6.4
994 */
995 function learn_press_get_enrolled_courses( $user_id ) {
996 return LP()->get_user( $user_id )->get( 'enrolled-courses' );
997 }
998
999 /**
1000 * @param $user_id
1001 *
1002 * @return WP_Query
1003 */
1004 function learn_press_get_own_courses( $user_id ) {
1005 $arr_query = array(
1006 'post_type' => 'lp_course',
1007 'author' => $user_id,
1008 'post_status' => 'publish',
1009 'ignore_sticky_posts' => true,
1010 'posts_per_page' => - 1,
1011 );
1012 $my_query = new WP_Query( $arr_query );
1013
1014 return $my_query;
1015 }
1016
1017 /**
1018 * Return array list of currency positions.
1019 *
1020 * @param bool|string $currency
1021 *
1022 * @return array
1023 */
1024 function learn_press_currency_positions( $currency = false ) {
1025 $positions = array(
1026 'left' => __( 'Left', 'learnpress' ),
1027 'right' => __( 'Right', 'learnpress' ),
1028 'left_with_space' => __( 'Left with space', 'learnpress' ),
1029 'right_with_space' => __( 'Right with space', 'learnpress' ),
1030 );
1031
1032 if ( false === $currency ) {
1033 $currency = learn_press_get_currency_symbol();
1034 }
1035
1036 $settings = LP_Settings::instance();
1037
1038 $thousands_separator = '';
1039 $decimals_separator = $settings->get( 'decimals_separator', '.' );
1040 $number_of_decimals = $settings->get( 'number_of_decimals', 2 );
1041
1042 if ( $number_of_decimals > 0 ) {
1043 $example = '69' . $decimals_separator . str_repeat( '9', $number_of_decimals );
1044 } else {
1045 $example = '69';
1046 }
1047
1048 foreach ( $positions as $pos => $text ) {
1049 switch ( $pos ) {
1050 case 'left':
1051 $text = sprintf( '%s ( %s%s )', $text, $currency, $example );
1052 break;
1053 case 'right':
1054 $text = sprintf( '%s ( %s%s )', $text, $example, $currency );
1055 break;
1056 case 'left_with_space':
1057 $text = sprintf( '%s ( %s %s )', $text, $currency, $example );
1058 break;
1059 case 'right_with_space':
1060 $text = sprintf( '%s ( %s %s )', $text, $example, $currency );
1061 break;
1062 }
1063 $positions[ $pos ] = $text;
1064 }
1065
1066 $positions = apply_filters( 'learn_press_currency_positions', $positions );
1067
1068 return apply_filters( 'learn-press/currency-positions', $positions );
1069 }
1070
1071 /**
1072 * @return array
1073 */
1074 function learn_press_get_payment_currencies() {
1075 return apply_filters( 'learn_press_get_payment_currencies', learn_press_currencies() );
1076 }
1077
1078 /**
1079 * Get the list of currencies with code and name.
1080 *
1081 * @return array
1082 * @version 3.0.0
1083 *
1084 * @author ThimPress
1085 */
1086 function learn_press_currencies() {
1087 $currencies = array(
1088 'AFN' => __( 'Afghan afghani', 'learnpress' ),
1089 'ALL' => __( 'Albanian lek', 'learnpress' ),
1090 'DZD' => __( 'Algerian dinar', 'learnpress' ),
1091 'EUR' => __( 'Euro', 'learnpress' ),
1092 'AOA' => __( 'Angolan kwanza', 'learnpress' ),
1093 'XCD' => __( 'East Caribbean dollar', 'learnpress' ),
1094 'ARS' => __( 'Argentine peso', 'learnpress' ),
1095 'AMD' => __( 'Armenian dram', 'learnpress' ),
1096 'AWG' => __( 'Aruban florin', 'learnpress' ),
1097 'AUD' => __( 'Australian dollar', 'learnpress' ),
1098 'AZN' => __( 'Azerbaijani manat', 'learnpress' ),
1099 'BSD' => __( 'Bahamian dollar', 'learnpress' ),
1100 'BHD' => __( 'Bahraini dinar', 'learnpress' ),
1101 'BDT' => __( 'Bangladeshi taka', 'learnpress' ),
1102 'BBD' => __( 'Barbadian dollar', 'learnpress' ),
1103 'BYR' => __( 'Belarusian ruble', 'learnpress' ),
1104 'BZD' => __( 'Belizean dollar', 'learnpress' ),
1105 'XOF' => __( 'West African CFA franc', 'learnpress' ),
1106 'BMD' => __( 'Bermudian dollar', 'learnpress' ),
1107 'BTN' => __( 'Bhutanese ngultrum', 'learnpress' ),
1108 'BOB' => __( 'Bolivian boliviano', 'learnpress' ),
1109 'USD' => __( 'US dollar', 'learnpress' ),
1110 'BAM' => __( 'Bosnia and Herzegovina convertible mark', 'learnpress' ),
1111 'BWP' => __( 'Botswana pula', 'learnpress' ),
1112 'BRL' => __( 'Brazilian real', 'learnpress' ),
1113 'BND' => __( 'Brunei dollar', 'learnpress' ),
1114 'BGN' => __( 'Bulgarian lev', 'learnpress' ),
1115 'MMK' => __( 'Burmese kyat', 'learnpress' ),
1116 'BIF' => __( 'Burundian franc', 'learnpress' ),
1117 'KHR' => __( 'Cambodian riel', 'learnpress' ),
1118 'XAF' => __( 'Central African CFA franc', 'learnpress' ),
1119 'CAD' => __( 'Canadian dollar', 'learnpress' ),
1120 'CVE' => __( 'Cape Verdean escudo', 'learnpress' ),
1121 'KYD' => __( 'Cayman Islands dollar', 'learnpress' ),
1122 'CLP' => __( 'Chilean peso', 'learnpress' ),
1123 'CNY' => __( 'Chinese renminbi', 'learnpress' ),
1124 'COP' => __( 'Colombian peso', 'learnpress' ),
1125 'KMF' => __( 'Comorian franc', 'learnpress' ),
1126 'CDF' => __( 'Congolese franc', 'learnpress' ),
1127 'NZD' => __( 'New Zealand dollar', 'learnpress' ),
1128 'CRC' => __( 'Costa Rican colón', 'learnpress' ),
1129 'HRK' => __( 'Croatian kuna', 'learnpress' ),
1130 'CUC' => __( 'Cuban peso', 'learnpress' ),
1131 'ANG' => __( 'Netherlands Antilles guilder', 'learnpress' ),
1132 'CZK' => __( 'Czech koruna', 'learnpress' ),
1133 'DKK' => __( 'Danish krone', 'learnpress' ),
1134 'DJF' => __( 'Djiboutian franc', 'learnpress' ),
1135 'DOP' => __( 'Dominican peso', 'learnpress' ),
1136 'EGP' => __( 'Egyptian pound', 'learnpress' ),
1137 'SVC' => __( 'Salvadoran colón', 'learnpress' ),
1138 'ERN' => __( 'Eritrean nakfa', 'learnpress' ),
1139 'ETB' => __( 'Ethiopian birr', 'learnpress' ),
1140 'FKP' => __( 'Falkland Islands pound', 'learnpress' ),
1141 'FJD' => __( 'Fijian dollar', 'learnpress' ),
1142 'XPF' => __( 'CFP franc', 'learnpress' ),
1143 'GMD' => __( 'Gambian dalasi', 'learnpress' ),
1144 'GEL' => __( 'Georgian lari', 'learnpress' ),
1145 'GHS' => __( 'Ghanian cedi', 'learnpress' ),
1146 'GIP' => __( 'Gibraltar pound', 'learnpress' ),
1147 'GTQ' => __( 'Guatemalan quetzal', 'learnpress' ),
1148 'GBP' => __( 'British pound', 'learnpress' ),
1149 'GNF' => __( 'Guinean franc', 'learnpress' ),
1150 'GYD' => __( 'Guyanese dollar', 'learnpress' ),
1151 'HTG' => __( 'Haitian gourde', 'learnpress' ),
1152 'HNL' => __( 'Honduran lempira', 'learnpress' ),
1153 'HKD' => __( 'Hong Kong dollar', 'learnpress' ),
1154 'HUF' => __( 'Hungarian forint', 'learnpress' ),
1155 'ISK' => __( 'Icelandic króna', 'learnpress' ),
1156 'INR' => __( 'Indian rupee', 'learnpress' ),
1157 'IDR' => __( 'Indonesian rupiah', 'learnpress' ),
1158 'IRR' => __( 'Iranian rial', 'learnpress' ),
1159 'IQD' => __( 'Iraqi dinar', 'learnpress' ),
1160 'ILS' => __( 'Israeli new sheqel', 'learnpress' ),
1161 'JMD' => __( 'Jamaican dollar', 'learnpress' ),
1162 'JPY' => __( 'Japanese yen ', 'learnpress' ),
1163 'JOD' => __( 'Jordanian dinar', 'learnpress' ),
1164 'KZT' => __( 'Kazakhstani tenge', 'learnpress' ),
1165 'KES' => __( 'Kenyan shilling', 'learnpress' ),
1166 'KPW' => __( 'North Korean won', 'learnpress' ),
1167 'KWD' => __( 'Kuwaiti dinar', 'learnpress' ),
1168 'KGS' => __( 'Kyrgyzstani som', 'learnpress' ),
1169 'KRW' => __( 'South Korean won', 'learnpress' ),
1170 'LAK' => __( 'Lao kip', 'learnpress' ),
1171 'LVL' => __( 'Latvian lats', 'learnpress' ),
1172 'LBP' => __( 'Lebanese pound', 'learnpress' ),
1173 'LSL' => __( 'Lesotho loti', 'learnpress' ),
1174 'LRD' => __( 'Liberian dollar', 'learnpress' ),
1175 'LD' => __( 'Libyan dinar', 'learnpress' ),
1176 'CHF' => __( 'Swiss franc', 'learnpress' ),
1177 'LTL' => __( 'Lithuanian litas', 'learnpress' ),
1178 'MOP' => __( 'Macanese pataca', 'learnpress' ),
1179 'MKD' => __( 'Macedonian denar', 'learnpress' ),
1180 'MGA' => __( 'Malagasy ariary', 'learnpress' ),
1181 'MWK' => __( 'Malawian kwacha', 'learnpress' ),
1182 'MYR' => __( 'Malaysian ringgit', 'learnpress' ),
1183 'MVR' => __( 'Maldivian rufiyaa', 'learnpress' ),
1184 'MRO' => __( 'Mauritanian ouguiya', 'learnpress' ),
1185 'MUR' => __( 'Mauritian rupee', 'learnpress' ),
1186 'MXN' => __( 'Mexican peso', 'learnpress' ),
1187 'MDL' => __( 'Moldovan leu', 'learnpress' ),
1188 'MNT' => __( 'Mongolian tugrik', 'learnpress' ),
1189 'MAD' => __( 'Moroccan dirham', 'learnpress' ),
1190 'MZN' => __( 'Mozambican metical', 'learnpress' ),
1191 'NAD' => __( 'Namibian dollar', 'learnpress' ),
1192 'NPR' => __( 'Nepalese rupee', 'learnpress' ),
1193 'NIO' => __( 'Nicaraguan córdoba', 'learnpress' ),
1194 'NGN' => __( 'Nigerian naira', 'learnpress' ),
1195 'NOK' => __( 'Norwegian krone', 'learnpress' ),
1196 'OMR' => __( 'Omani rial', 'learnpress' ),
1197 'PKR' => __( 'Pakistani rupee', 'learnpress' ),
1198 'PAB' => __( 'Panamanian balboa', 'learnpress' ),
1199 'PGK' => __( 'Papua New Guinea kina', 'learnpress' ),
1200 'PYG' => __( 'Paraguayan guarani', 'learnpress' ),
1201 'PEN' => __( 'Peruvian nuevo sol', 'learnpress' ),
1202 'PHP' => __( 'Philippine peso', 'learnpress' ),
1203 'PLN' => __( 'Polish zloty', 'learnpress' ),
1204 'QAR' => __( 'Qatari riyal', 'learnpress' ),
1205 'RON' => __( 'Romanian leu', 'learnpress' ),
1206 'RUB' => __( 'Russian ruble', 'learnpress' ),
1207 'RWF' => __( 'Rwandan franc', 'learnpress' ),
1208 'WST' => __( 'Samoan tālā', 'learnpress' ),
1209 'STD' => __( 'São Tomé and Príncipe dobra', 'learnpress' ),
1210 'SAR' => __( 'Saudi riyal', 'learnpress' ),
1211 'RSD' => __( 'Serbian dinar', 'learnpress' ),
1212 'SCR' => __( 'Seychellois rupee', 'learnpress' ),
1213 'SLL' => __( 'Sierra Leonean leone', 'learnpress' ),
1214 'SGD' => __( 'Singapore dollar', 'learnpress' ),
1215 'SBD' => __( 'Solomon Islands dollar', 'learnpress' ),
1216 'SOS' => __( 'Somali shilling', 'learnpress' ),
1217 'ZAR' => __( 'South African rand', 'learnpress' ),
1218 'LKR' => __( 'Sri Lankan rupee', 'learnpress' ),
1219 'SHP' => __( 'St. Helena pound', 'learnpress' ),
1220 'SDG' => __( 'Sudanese pound', 'learnpress' ),
1221 'SRD' => __( 'Surinamese dollar', 'learnpress' ),
1222 'SZL' => __( 'Swazi lilangeni', 'learnpress' ),
1223 'SEK' => __( 'Swedish krona', 'learnpress' ),
1224 'SYP' => __( 'Syrian pound', 'learnpress' ),
1225 'TWD' => __( 'New Taiwan dollar', 'learnpress' ),
1226 'TJS' => __( 'Tajikistani somoni', 'learnpress' ),
1227 'TZS' => __( 'Tanzanian shilling', 'learnpress' ),
1228 'THB' => __( 'Thai baht ', 'learnpress' ),
1229 'TOP' => __( 'Tongan pa’anga', 'learnpress' ),
1230 'TTD' => __( 'Trinidad and Tobago dollar', 'learnpress' ),
1231 'TND' => __( 'Tunisian dinar', 'learnpress' ),
1232 'TRY' => __( 'Turkish lira', 'learnpress' ),
1233 'TMT' => __( 'Turkmenistani manat', 'learnpress' ),
1234 'UGX' => __( 'Ugandan shilling', 'learnpress' ),
1235 'UAH' => __( 'Ukrainian hryvnia', 'learnpress' ),
1236 'AED' => __( 'United Arab Emirates dirham', 'learnpress' ),
1237 'UYU' => __( 'Uruguayan peso', 'learnpress' ),
1238 'UZS' => __( 'Uzbekistani som', 'learnpress' ),
1239 'VUV' => __( 'Vanuatu vatu', 'learnpress' ),
1240 'VEF' => __( 'Venezuelan bolivar', 'learnpress' ),
1241 'VND' => __( 'Vietnamese dong', 'learnpress' ),
1242 'YER' => __( 'Yemeni rial', 'learnpress' ),
1243 'ZMK' => __( 'Zambian kwacha', 'learnpress' ),
1244 'ZWL' => __( 'Zimbabwean dollar', 'learnpress' ),
1245 'JEP' => __( 'Jersey pound', 'learnpress' ),
1246 'LYD' => __( 'Libyan dinar', 'learnpress' ),
1247 );
1248
1249 asort( $currencies );
1250
1251 return apply_filters( 'learn-press/currencies', $currencies );
1252 }
1253
1254 /**
1255 * Get current setting of currency.
1256 *
1257 * @return string
1258 */
1259 function learn_press_get_currency() {
1260 $currency = apply_filters( 'learn_press_currency', LP_Settings::instance()->get( 'currency', 'USD' ) );
1261
1262 return apply_filters( 'learn-press/currency', $currency );
1263 }
1264
1265 /**
1266 * Return list of common symbols of the currencies on the world.
1267 *
1268 * @return array
1269 */
1270 function learn_press_currency_symbols() {
1271 $symbols = array(
1272 'AED' => '&#x62f;.&#x625;',
1273 'AFN' => '&#x60b;',
1274 'ALL' => 'L',
1275 'AMD' => 'AMD',
1276 'ANG' => '&fnof;',
1277 'AOA' => 'Kz',
1278 'ARS' => '&#36;',
1279 'AUD' => '&#36;',
1280 'AWG' => 'Afl.',
1281 'AZN' => 'AZN',
1282 'BAM' => 'KM',
1283 'BBD' => '&#36;',
1284 'BDT' => '&#2547;&nbsp;',
1285 'BGN' => '&#1083;&#1074;.',
1286 'BHD' => '.&#x62f;.&#x628;',
1287 'BIF' => 'Fr',
1288 'BMD' => '&#36;',
1289 'BND' => '&#36;',
1290 'BOB' => 'Bs.',
1291 'BRL' => '&#82;&#36;',
1292 'BSD' => '&#36;',
1293 'BTC' => '&#3647;',
1294 'BTN' => 'Nu.',
1295 'BWP' => 'P',
1296 'BYR' => 'Br',
1297 'BYN' => 'Br',
1298 'BZD' => '&#36;',
1299 'CAD' => '&#36;',
1300 'CDF' => 'Fr',
1301 'CHF' => '&#67;&#72;&#70;',
1302 'CLP' => '&#36;',
1303 'CNY' => '&yen;',
1304 'COP' => '&#36;',
1305 'CRC' => '&#x20a1;',
1306 'CUC' => '&#36;',
1307 'CUP' => '&#36;',
1308 'CVE' => '&#36;',
1309 'CZK' => '&#75;&#269;',
1310 'DJF' => 'Fr',
1311 'DKK' => 'DKK',
1312 'DOP' => 'RD&#36;',
1313 'DZD' => '&#x62f;.&#x62c;',
1314 'EGP' => 'EGP',
1315 'ERN' => 'Nfk',
1316 'ETB' => 'Br',
1317 'EUR' => '&euro;',
1318 'FJD' => '&#36;',
1319 'FKP' => '&pound;',
1320 'GBP' => '&pound;',
1321 'GEL' => '&#x20be;',
1322 'GGP' => '&pound;',
1323 'GHS' => '&#x20b5;',
1324 'GIP' => '&pound;',
1325 'GMD' => 'D',
1326 'GNF' => 'Fr',
1327 'GTQ' => 'Q',
1328 'GYD' => '&#36;',
1329 'HKD' => '&#36;',
1330 'HNL' => 'L',
1331 'HRK' => 'kn',
1332 'HTG' => 'G',
1333 'HUF' => '&#70;&#116;',
1334 'IDR' => 'Rp',
1335 'ILS' => '&#8362;',
1336 'IMP' => '&pound;',
1337 'INR' => '&#8377;',
1338 'IQD' => '&#x639;.&#x62f;',
1339 'IRR' => '&#xfdfc;',
1340 'IRT' => '&#x062A;&#x0648;&#x0645;&#x0627;&#x0646;',
1341 'ISK' => 'kr.',
1342 'JEP' => '&pound;',
1343 'JMD' => '&#36;',
1344 'JOD' => '&#x62f;.&#x627;',
1345 'JPY' => '&yen;',
1346 'KES' => 'KSh',
1347 'KGS' => '&#x441;&#x43e;&#x43c;',
1348 'KHR' => '&#x17db;',
1349 'KMF' => 'Fr',
1350 'KPW' => '&#x20a9;',
1351 'KRW' => '&#8361;',
1352 'KWD' => '&#x62f;.&#x643;',
1353 'KYD' => '&#36;',
1354 'KZT' => '&#8376;',
1355 'LAK' => '&#8365;',
1356 'LBP' => '&#x644;.&#x644;',
1357 'LKR' => '&#xdbb;&#xdd4;',
1358 'LRD' => '&#36;',
1359 'LSL' => 'L',
1360 'LYD' => '&#x644;.&#x62f;',
1361 'MAD' => '&#x62f;.&#x645;.',
1362 'MDL' => 'MDL',
1363 'MGA' => 'Ar',
1364 'MKD' => '&#x434;&#x435;&#x43d;',
1365 'MMK' => 'Ks',
1366 'MNT' => '&#x20ae;',
1367 'MOP' => 'P',
1368 'MRU' => 'UM',
1369 'MUR' => '&#x20a8;',
1370 'MVR' => '.&#x783;',
1371 'MWK' => 'MK',
1372 'MXN' => '&#36;',
1373 'MYR' => '&#82;&#77;',
1374 'MZN' => 'MT',
1375 'NAD' => 'N&#36;',
1376 'NGN' => '&#8358;',
1377 'NIO' => 'C&#36;',
1378 'NOK' => '&#107;&#114;',
1379 'NPR' => '&#8360;',
1380 'NZD' => '&#36;',
1381 'OMR' => '&#x631;.&#x639;.',
1382 'PAB' => 'B/.',
1383 'PEN' => 'S/',
1384 'PGK' => 'K',
1385 'PHP' => '&#8369;',
1386 'PKR' => '&#8360;',
1387 'PLN' => '&#122;&#322;',
1388 'PRB' => '&#x440;.',
1389 'PYG' => '&#8370;',
1390 'QAR' => '&#x631;.&#x642;',
1391 'RMB' => '&yen;',
1392 'RON' => 'lei',
1393 'RSD' => '&#1088;&#1089;&#1076;',
1394 'RUB' => '&#8381;',
1395 'RWF' => 'Fr',
1396 'SAR' => '&#x631;.&#x633;',
1397 'SBD' => '&#36;',
1398 'SCR' => '&#x20a8;',
1399 'SDG' => '&#x62c;.&#x633;.',
1400 'SEK' => '&#107;&#114;',
1401 'SGD' => '&#36;',
1402 'SHP' => '&pound;',
1403 'SLL' => 'Le',
1404 'SOS' => 'Sh',
1405 'SRD' => '&#36;',
1406 'SSP' => '&pound;',
1407 'STN' => 'Db',
1408 'SYP' => '&#x644;.&#x633;',
1409 'SZL' => 'L',
1410 'THB' => '&#3647;',
1411 'TJS' => '&#x405;&#x41c;',
1412 'TMT' => 'm',
1413 'TND' => '&#x62f;.&#x62a;',
1414 'TOP' => 'T&#36;',
1415 'TRY' => '&#8378;',
1416 'TTD' => '&#36;',
1417 'TWD' => '&#78;&#84;&#36;',
1418 'TZS' => 'Sh',
1419 'UAH' => '&#8372;',
1420 'UGX' => 'UGX',
1421 'USD' => '&#36;',
1422 'UYU' => '&#36;',
1423 'UZS' => 'UZS',
1424 'VEF' => 'Bs F',
1425 'VES' => 'Bs.S',
1426 'VND' => '&#8363;',
1427 'VUV' => 'Vt',
1428 'WST' => 'T',
1429 'XAF' => 'CFA',
1430 'XCD' => '&#36;',
1431 'XOF' => 'CFA',
1432 'XPF' => 'Fr',
1433 'YER' => '&#xfdfc;',
1434 'ZAR' => '&#82;',
1435 'ZMW' => 'ZK',
1436 );
1437
1438 return apply_filters( 'learn-press/currency-symbols', $symbols );
1439 }
1440
1441 /**
1442 * Return currency symbol from the code.
1443 *
1444 * @param string $currency
1445 *
1446 * @return string
1447 */
1448 function learn_press_get_currency_symbol( $currency = '' ) {
1449 if ( ! $currency ) {
1450 $currency = learn_press_get_currency();
1451 }
1452 $symbols = learn_press_currency_symbols();
1453 $currency_symbol = isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : '';
1454
1455 $currency_symbol = apply_filters( 'learn_press_currency_symbol', $currency_symbol, $currency );
1456
1457 return apply_filters( 'learn-press/currency-symbol', $currency_symbol, $currency );
1458 }
1459
1460 /**
1461 * Get static page for LP page by name.
1462 *
1463 * @param string $key
1464 *
1465 * @return string
1466 * @editor tungnx
1467 * @modify 4.1.4
1468 */
1469 function learn_press_get_page_link( string $key ): string {
1470 $page_id = learn_press_get_page_id( $key );
1471 $link = '';
1472
1473 if ( $page_id && get_post_status( $page_id ) == 'publish' ) {
1474 $permalink = get_permalink( $page_id );
1475 $link = apply_filters( 'learn-press/get-page-link', trailingslashit( $permalink ), $page_id, $key );
1476 }
1477
1478 return $link;
1479 }
1480
1481 /**
1482 * Get static page for LP page by name.
1483 *
1484 * @param string $key
1485 *
1486 * @return string
1487 */
1488 function learn_press_get_page_title( $key ) {
1489 $page_id = LP_Settings::instance()->get( $key . '_page_id' );
1490 $title = '';
1491
1492 if ( $page_id && get_post_status( $page_id ) == 'publish' ) {
1493 $title = apply_filters( 'learn-press/get-page-title', get_the_title( $page_id ), $page_id, $key );
1494 }
1495
1496 return apply_filters( 'learn-press/get-page-' . $key . '-title', $title, $page_id );
1497 }
1498
1499 /**
1500 * get the ID of a course by order ID
1501 *
1502 * @param $order_id
1503 *
1504 * @return bool|mixed
1505 */
1506 function learn_press_get_course_by_order( $order_id ) {
1507 $order_items = get_post_meta( $order_id, '_learn_press_order_items', true );
1508
1509 if ( $order_items && $order_items->products ) {
1510 $array_keys = array_keys( $order_items->products );
1511
1512 return reset( $array_keys );
1513 }
1514
1515 return false;
1516 }
1517
1518 /**
1519 * Convert a number of seconds to weeks/days/hours.
1520 *
1521 * @param int $secs
1522 *
1523 * @return bool|string
1524 */
1525 function learn_press_seconds_to_weeks( int $secs = 0 ) {
1526 $secs = (int) $secs;
1527
1528 if ( 0 === $secs ) {
1529 return false;
1530 }
1531 // variables for holding values.
1532 $mins = 0;
1533 $hours = 0;
1534 $days = 0;
1535 $weeks = 0;
1536 // calculations.
1537 if ( $secs >= 60 ) {
1538 $mins = (int) ( $secs / 60 );
1539 $secs = $secs % 60;
1540 }
1541 if ( $mins >= 60 ) {
1542 $hours = (int) ( $mins / 60 );
1543 $mins = $mins % 60;
1544 }
1545 if ( $hours >= 24 ) {
1546 $days = (int) ( $hours / 24 );
1547 $hours = $hours % 24;
1548 }
1549 if ( $days >= 7 ) {
1550 $weeks = (int) ( $days / 7 );
1551 $days = $days % 7;
1552 }
1553 // format result.
1554 $result = '';
1555 if ( $weeks ) {
1556 $result .= sprintf( _n( '%s week', '%s weeks', $weeks, 'learnpress' ), $weeks ) . ' ';
1557 }
1558
1559 if ( $days ) {
1560 $result .= sprintf( _n( '%s day', '%s days', $days, 'learnpress' ), $days ) . ' ';
1561 }
1562
1563 if ( ! $weeks ) {
1564 if ( $hours ) {
1565 $result .= sprintf( _n( '%s hour', '%s hours', $hours, 'learnpress' ), $hours ) . ' ';
1566 }
1567
1568 if ( $mins ) {
1569 $result .= sprintf( _n( '%s minute', '%s minutes', $mins, 'learnpress' ), $mins ) . ' ';
1570 }
1571 }
1572
1573 $result = rtrim( $result );
1574
1575 return $result;
1576 }
1577
1578 /**
1579 * @depecated since version 4.1.6.6
1580 */
1581 /*function learn_press_get_query_var( $var ) {
1582 global $wp_query;
1583
1584 $return = null;
1585 if ( ! empty( $wp_query->query_vars[ $var ] ) ) {
1586 $return = $wp_query->query_vars[ $var ];
1587 } elseif ( ! empty( $_REQUEST[ $var ] ) ) {
1588 $return = $_REQUEST[ $var ];
1589 }
1590
1591 return apply_filters( 'learn_press_query_var', $return, $var );
1592 }*/
1593
1594 function learn_press_course_lesson_permalink_friendly( $permalink, $lesson_id, $course_id ) {
1595 if ( '' != get_option( 'permalink_structure' ) ) {
1596 if ( preg_match( '!\?lesson=([^\?\&]*)!', $permalink, $matches ) ) {
1597 $permalink = preg_replace(
1598 '!/?\?lesson=([^\?\&]*)!',
1599 '/' . basename( get_permalink( $matches[1] ) ),
1600 untrailingslashit( $permalink )
1601 );
1602 }
1603 }
1604
1605 return $permalink;
1606 }
1607
1608 function learn_press_course_question_permalink_friendly( $permalink, $lesson_id, $course_id ) {
1609 if ( '' != get_option( 'permalink_structure' ) ) {
1610 if ( preg_match( '!\?lesson=([^\?\&]*)!', $permalink, $matches ) ) {
1611 $permalink = preg_replace(
1612 '!/?\?lesson=([^\?\&]*)!',
1613 '/' . basename( get_permalink( $matches[1] ) ),
1614 untrailingslashit( $permalink )
1615 );
1616 }
1617 }
1618
1619 return $permalink;
1620 }
1621
1622 add_filter( 'learn_press_course_lesson_permalink', 'learn_press_course_lesson_permalink_friendly', 10, 3 );
1623
1624 function learn_press_user_maybe_is_a_teacher( $user = null ) {
1625 if ( ! $user ) {
1626 $user = learn_press_get_current_user();
1627 } elseif ( is_numeric( $user ) ) {
1628 $user = learn_press_get_user( $user );
1629 }
1630 if ( ! $user ) {
1631 return false;
1632 }
1633
1634 $role = $user->has_role( 'administrator' ) ? 'administrator' : false;
1635 if ( ! $role ) {
1636 $role = $user->has_role( 'lp_teacher' ) ? 'lp_teacher' : false;
1637 }
1638
1639 return apply_filters( 'learn-press/user/is-teacher', $role, $user->get_id() );
1640 }
1641
1642 function learn_press_become_teacher_sent( $user_id = 0 ) {
1643 if ( func_num_args() == 0 ) {
1644 $user_id = get_current_user_id();
1645 }
1646
1647 return 'yes' === get_user_meta( $user_id, '_requested_become_teacher', true );
1648 }
1649
1650 function _learn_press_translate_user_roles( $translations, $text, $context, $domain ) {
1651 $plugin_domain = 'learnpress';
1652 $roles = array( 'LP Instructor' );
1653
1654 if ( $context === 'User role' && in_array( $text, $roles ) && $domain !== $plugin_domain ) {
1655 return translate_with_gettext_context( $text, $context, $plugin_domain );
1656 }
1657
1658 return $translations;
1659 }
1660
1661 add_filter( 'gettext_with_context', '_learn_press_translate_user_roles', 10, 4 );
1662
1663 /**
1664 * Modifies the statement $where to make the search works correct
1665 *
1666 * @param string
1667 *
1668 * @return string
1669 */
1670 function learn_press_posts_where_statement_search( $where ) {
1671 // gets the global query var object
1672 global $wp_query, $wpdb;
1673
1674 /**
1675 * Need to wrap this block into () in order to make it works correctly when filter by specific post type => maybe a bug :)
1676 * from => ( wp_2_posts.post_status = 'publish' OR wp_2_posts.post_status = 'private') OR wp_2_terms.name LIKE '%s%'
1677 * to => ( ( wp_2_posts.post_status = 'publish' OR wp_2_posts.post_status = 'private') OR wp_2_terms.name LIKE '%s%' )
1678 */
1679 $a = preg_match( '!(' . $wpdb->posts . '.post_status)!', $where );
1680 $b = preg_match( '!(OR\s+' . $wpdb->terms . '.name LIKE \'%' . $wp_query->get( 's' ) . '%\')!', $where );
1681
1682 if ( $a && $b ) {
1683 // append ( to the start of the block
1684 $where = preg_replace( '!(' . $wpdb->posts . '.post_status)!', '( $1', $where, 1 );
1685
1686 // append ) to the end of the block
1687 $where = preg_replace(
1688 '!(OR\s+' . $wpdb->terms . '.name LIKE \'%' . $wp_query->get( 's' ) . '%\')!',
1689 '$1 )',
1690 $where
1691 );
1692 }
1693 remove_filter( 'posts_where', 'learn_press_posts_where_statement_search', 99 );
1694
1695 return $where;
1696 }
1697
1698 /**
1699 * Filter post type for search function
1700 * Only search lpr_course if see the param ref=course in request
1701 *
1702 * @param WP_Query $q
1703 */
1704 function learn_press_filter_search( $q ) {
1705 if ( $q->is_main_query() && $q->is_search() && ( ! empty( $_REQUEST['ref'] ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course' ) ) {
1706 $q->set( 'post_type', 'lp_course' );
1707
1708 add_filter( 'posts_where', 'learn_press_posts_where_statement_search', 99 );
1709 remove_filter( 'pre_get_posts', 'learn_press_filter_search', 99 );
1710 }
1711 }
1712
1713 add_filter( 'pre_get_posts', 'learn_press_filter_search', 99 );
1714
1715 if ( ! function_exists( 'learn_press_send_json' ) ) {
1716 function learn_press_send_json( $data ) {
1717 echo '<-- LP_AJAX_START -->';
1718 echo wp_json_encode( $data );
1719 echo '<-- LP_AJAX_END -->';
1720 die;
1721 }
1722 }
1723
1724 /**
1725 * Send json with success signal to browser.
1726 *
1727 * @param array|object|WP_Error $data
1728 *
1729 * @since 3.0.1
1730 */
1731 function learn_press_send_json_error( $data = '' ) {
1732 $response = array( 'success' => false );
1733
1734 if ( isset( $data ) ) {
1735 if ( is_wp_error( $data ) ) {
1736 $result = array();
1737 foreach ( $data->errors as $code => $messages ) {
1738 foreach ( $messages as $message ) {
1739 $result[] = array(
1740 'code' => $code,
1741 'message' => $message,
1742 );
1743 }
1744 }
1745
1746 $response['data'] = $result;
1747 } else {
1748 $response['data'] = $data;
1749 }
1750 }
1751
1752 learn_press_send_json( $response );
1753 }
1754
1755 /**
1756 * Send json with error signal to browser.
1757 *
1758 * @param array|object|WP_Error $data
1759 *
1760 * @since 3.0.0
1761 */
1762 function learn_press_send_json_success( $data = '' ) {
1763 $response = array( 'success' => true );
1764
1765 if ( isset( $data ) ) {
1766 $response['data'] = $data;
1767 }
1768
1769 learn_press_send_json( $response );
1770 }
1771
1772 /**
1773 * Check if ajax is calling then send json data.
1774 *
1775 * @param array $data
1776 * @param mixed $callback
1777 *
1778 * @return bool
1779 */
1780 function learn_press_maybe_send_json( $data, $callback = null ) {
1781 if ( learn_press_is_ajax() ) {
1782 is_callable( $callback ) && call_user_func( $callback );
1783 if ( empty( $data['message'] ) && ( $message = learn_press_get_messages( true ) ) ) {
1784 $data['message'] = $message;
1785 }
1786 learn_press_send_json( $data );
1787 }
1788
1789 return false;
1790 }
1791
1792 /**
1793 * Get data from request.
1794 *
1795 * @param string $key
1796 * @param mixed $default
1797 * @param mixed $hash
1798 *
1799 * @return mixed
1800 */
1801 function learn_press_get_request( $key, $default = null, $hash = null ) {
1802 $return = LP_Helper::sanitize_params_submitted( $default );
1803
1804 if ( $hash ) {
1805 if ( ! empty( $hash[ $key ] ) ) {
1806 $return = LP_Helper::sanitize_params_submitted( $hash[ $key ] );
1807 }
1808 } else {
1809 if ( ! empty( $_POST[ $key ] ) ) {
1810 $return = LP_Helper::sanitize_params_submitted( $_POST[ $key ] );
1811 } elseif ( ! empty( $_GET[ $key ] ) ) {
1812 $return = LP_Helper::sanitize_params_submitted( $_GET[ $key ] );
1813 } elseif ( ! empty( $_REQUEST[ $key ] ) ) {
1814 $return = LP_Helper::sanitize_params_submitted( $_REQUEST[ $key ] );
1815 }
1816 }
1817
1818 return $return;
1819 }
1820
1821 /**
1822 * @return mixed
1823 */
1824 function is_learnpress() {
1825 return apply_filters(
1826 'is_learnpress',
1827 ( learn_press_is_course_archive() || learn_press_is_course_taxonomy() || learn_press_is_course() || learn_press_is_quiz() || learn_press_is_search() ) ? true : false
1828 );
1829 }
1830
1831 if ( ! function_exists( 'learn_press_is_search' ) ) {
1832 function learn_press_is_search() {
1833 return array_key_exists( 's', $_REQUEST ) && array_key_exists( 'ref', $_REQUEST ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course';
1834 }
1835 }
1836
1837 if ( ! function_exists( 'learn_press_is_courses' ) ) {
1838 function learn_press_is_courses() {
1839 return learn_press_is_course_archive();
1840 }
1841 }
1842
1843
1844 if ( ! function_exists( 'learn_press_is_course_archive' ) ) {
1845 function learn_press_is_course_archive() {
1846 global $wp_query;
1847
1848 $queried_object_id = ! empty( $wp_query->queried_object ) ? $wp_query->queried_object : 0;
1849 $is_courses = defined( 'LEARNPRESS_IS_COURSES' ) && LEARNPRESS_IS_COURSES;
1850 $is_tag = defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG || is_tax( 'course_tag' );
1851 $is_category = defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY || is_tax( 'course_category' );
1852 $page_id = learn_press_get_page_id( 'courses' );
1853
1854 return ( $is_courses || $is_category || $is_tag ) || is_post_type_archive( 'lp_course' ) || ( $page_id && ( $queried_object_id && is_page( $page_id ) ) );
1855 }
1856 }
1857
1858 if ( ! function_exists( 'learn_press_is_course_tax' ) ) {
1859 function learn_press_is_course_tax() {
1860 return is_tax( get_object_taxonomies( LP_COURSE_CPT ) );
1861 }
1862 }
1863
1864 if ( ! function_exists( 'learn_press_is_course_taxonomy' ) ) {
1865 function learn_press_is_course_taxonomy() {
1866 return ( defined( 'LEARNPRESS_IS_TAX' ) && LEARNPRESS_IS_TAX ) || learn_press_is_course_tax();
1867 }
1868 }
1869
1870
1871 if ( ! function_exists( 'learn_press_is_course_category' ) ) {
1872 function learn_press_is_course_category( $term = '' ) {
1873 return ( defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY ) || is_tax( 'course_category', $term );
1874 }
1875 }
1876
1877
1878 if ( ! function_exists( 'learn_press_is_course_tag' ) ) {
1879 function learn_press_is_course_tag( $term = '' ) {
1880 return ( defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG ) || is_tax( 'course_tag', $term );
1881 }
1882 }
1883
1884 if ( ! function_exists( 'learn_press_is_course' ) ) {
1885 function learn_press_is_course() {
1886 return is_singular( array( LP_COURSE_CPT ) );
1887 }
1888 }
1889
1890 if ( ! function_exists( 'learn_press_is_lesson' ) ) {
1891 function learn_press_is_lesson() {
1892 return is_singular( array( LP_LESSON_CPT ) );
1893 }
1894 }
1895
1896 if ( ! function_exists( 'learn_press_is_quiz' ) ) {
1897 function learn_press_is_quiz() {
1898 return is_singular( array( LP_QUIZ_CPT ) );
1899 }
1900 }
1901
1902 function lp_content_has_shortcode( $tag = '' ) {
1903 global $post;
1904
1905 return is_singular() && is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, $tag );
1906 }
1907
1908 /**
1909 * Returns true when viewing profile page.
1910 *
1911 * @return bool
1912 */
1913 function learn_press_is_profile() {
1914 $page_id = learn_press_get_page_id( 'profile' );
1915
1916 if ( $page_id && is_page( $page_id ) || lp_content_has_shortcode( 'learn_press_profile' ) ) {
1917 return true;
1918 }
1919
1920 return apply_filters( 'learn-press/is-profile', false );
1921 }
1922
1923 /**
1924 * Return true if user is in checking out page
1925 *
1926 * @return bool
1927 */
1928 function learn_press_is_checkout() {
1929 $page_id = learn_press_get_page_id( 'checkout' );
1930
1931 if ( $page_id && is_page( $page_id ) ) {
1932 return true;
1933 }
1934
1935 return apply_filters( 'learn-press/is-checkout', false );
1936 }
1937
1938 /**
1939 * Return register permalink
1940 *
1941 * @return mixed
1942 */
1943 function learn_press_get_register_url() {
1944 return apply_filters( 'learn_press_register_url', wp_registration_url() );
1945 }
1946
1947 /**
1948 * Add a new notice into queue
1949 *
1950 * @param string
1951 * @param string
1952 *
1953 * @return mixed
1954 */
1955 function learn_press_add_notice( $message, $type = 'updated' ) {
1956 LP_Admin_Notice::instance()->add( $message, $type );
1957 }
1958
1959 /**
1960 * Set user's cookie
1961 *
1962 * @param $name
1963 * @param $value
1964 * @param int $expire
1965 * @param bool $secure
1966 *
1967 * @editor tungnx
1968 * @version 1.0.2
1969 */
1970 function learn_press_setcookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) {
1971 $secure = ( 'https' === parse_url( wp_login_url(), PHP_URL_SCHEME ) );
1972
1973 @setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, $httponly );
1974 }
1975
1976 /**
1977 * Clear cookie
1978 *
1979 * @param $name
1980 */
1981 function learn_press_remove_cookie( $name ) {
1982 setcookie( $name, '', time() - YEAR_IN_SECONDS, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN );
1983
1984 if ( array_key_exists( $name, $_COOKIE ) ) {
1985 unset( $_COOKIE[ $name ] );
1986 }
1987 }
1988
1989 /**
1990 * Filter the login url so third-party can be customize
1991 *
1992 * @param string $redirect
1993 *
1994 * @return mixed
1995 */
1996 function learn_press_get_login_url( $redirect = null ) {
1997 $url = wp_login_url( $redirect );
1998 $profile_page = learn_press_get_page_link( 'profile' );
1999
2000 if ( 'yes' === LP_Settings::instance()->get( 'enable_login_profile' ) && $profile_page ) {
2001 $parse_url = parse_url( $url );
2002 $url = $profile_page . ( ! empty( $parse_url['query'] ) ? '?' . $parse_url['query'] : '' );
2003 }
2004
2005 return apply_filters( 'learn-press/login-url', $url );
2006 }
2007
2008 /**
2009 * Add variable to an url by checking the permalink structure.
2010 *
2011 * @param string $name
2012 * @param string $value
2013 * @param string $url
2014 *
2015 * @return string
2016 */
2017 function learn_press_get_endpoint_url( $name, $value, $url ) {
2018 if ( ! $url ) {
2019 $url = get_permalink();
2020 }
2021
2022 // Map endpoint to options
2023 $name = isset( LP()->query_vars[ $name ] ) ? LP()->query_vars[ $name ] : $name;
2024
2025 if ( get_option( 'permalink_structure' ) ) {
2026 if ( strstr( $url, '?' ) ) {
2027 $query_string = '?' . parse_url( $url, PHP_URL_QUERY );
2028 $url = current( explode( '?', $url ) );
2029 } else {
2030 $query_string = '';
2031 }
2032 $url = trailingslashit( $url ) . ( $name ? $name . '/' : '' ) . $value . $query_string;
2033
2034 } else {
2035 $url = esc_url_raw( add_query_arg( $name, $value, $url ) );
2036 }
2037
2038 return apply_filters( 'learn_press_get_endpoint_url', esc_url_raw( $url ), $name, $value, $url );
2039 }
2040
2041 /**
2042 * Add all endpoints from settings to the pages.
2043 */
2044 function learn_press_add_endpoints() {
2045 $settings = LP_Settings::instance();
2046
2047 $endpoints = $settings->get_checkout_endpoints();
2048 if ( $endpoints ) {
2049 foreach ( $endpoints as $endpoint => $value ) {
2050 LP()->query_vars[ $endpoint ] = $value;
2051 add_rewrite_endpoint( $value, EP_PAGES );
2052 }
2053 }
2054
2055 $endpoints = $settings->get_profile_endpoints();
2056 if ( $endpoints ) {
2057 foreach ( $endpoints as $endpoint => $value ) {
2058 LP()->query_vars[ $endpoint ] = $value;
2059 add_rewrite_endpoint( $value, EP_PAGES );
2060 }
2061 }
2062
2063 $endpoints = $settings->get( 'quiz_endpoints' );
2064 if ( $endpoints ) {
2065 foreach ( $endpoints as $endpoint => $value ) {
2066 $endpoint = preg_replace( '!_!', '-', $endpoint );
2067 LP()->query_vars[ $endpoint ] = $value;
2068 add_rewrite_endpoint(
2069 $value, /*EP_ROOT | */
2070 EP_PAGES
2071 );
2072 }
2073 }
2074 }
2075
2076 add_action( 'init', 'learn_press_add_endpoints' );
2077
2078 function learn_press_is_yes( $value ) {
2079 return ( $value === 1 ) || ( $value === '1' ) || ( $value == 'yes' ) || ( $value == true ) || ( $value == 'on' );
2080 }
2081
2082 /**
2083 * @param mixed $value
2084 *
2085 * @return bool
2086 */
2087 function _is_false_value( $value ) {
2088 if ( is_numeric( $value ) ) {
2089 return $value == 0;
2090 } elseif ( is_string( $value ) ) {
2091 return ( empty( $value ) || is_null( $value ) || in_array( $value, array( 'no', 'off', 'false' ) ) );
2092 }
2093
2094 return ! ! $value;
2095 }
2096
2097 /**
2098 * Map the query vars from LP to query vars of WP core
2099 * when WP parse the requesting.
2100 */
2101 function learn_press_parse_request() {
2102 global $wp;
2103
2104 // Map query vars to their keys, or get them if endpoints are not supported
2105 foreach ( LP()->query_vars as $key => $var ) {
2106 if ( isset( $_GET[ $var ] ) ) {
2107 $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $_GET[ $var ] ?? '' );
2108 } elseif ( isset( $wp->query_vars[ $var ] ) ) {
2109 $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $wp->query_vars[ $var ] ?? '' );
2110 }
2111 }
2112 }
2113
2114 add_action( 'parse_request', 'learn_press_parse_request' );
2115
2116 if ( ! function_exists( 'learn_press_reset_auto_increment' ) ) {
2117 /**
2118 * Reset AUTO INCREMENT of the table.
2119 *
2120 * @param $table
2121 */
2122 function learn_press_reset_auto_increment( $table ) {
2123 global $wpdb;
2124 $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}$table AUTO_INCREMENT = %d", 1 ) );
2125 }
2126 }
2127
2128 /**
2129 * @param string $handle
2130 * @param bool $hash
2131 *
2132 * @return string
2133 */
2134 function learn_press_get_log_file_path( $handle, $hash = false ) {
2135 if ( $hash ) {
2136 $hash = '-' . sanitize_file_name( wp_hash( $handle ) );
2137 }
2138
2139 return trailingslashit( LP_LOG_PATH ) . $handle . $hash . '.log';
2140 }
2141
2142 /**
2143 * Get the cart object in checkout page
2144 *
2145 * @return LP_Cart
2146 */
2147 function learn_press_get_checkout_cart() {
2148 return apply_filters( 'learn_press_checkout_cart', LP()->cart );
2149 }
2150
2151 /*function learn_press_front_scripts() {
2152 if ( is_admin() ) {
2153 return;
2154 }
2155 $js = array(
2156 'ajax' => admin_url( 'admin-ajax.php' ),
2157 'plugin_url' => LP()->plugin_url(),
2158 'siteurl' => home_url(),
2159 'current_url' => learn_press_get_current_url(),
2160 'localize' => array(
2161 'button_ok' => __( 'OK', 'learnpress' ),
2162 'button_cancel' => __( 'Cancel', 'learnpress' ),
2163 'button_yes' => __( 'Yes', 'learnpress' ),
2164 'button_no' => __( 'No', 'learnpress' ),
2165 ),
2166 );
2167 foreach ( $js as $k => $v ) {
2168 LP_Assets::add_param( $k, $v, array( 'learn-press-single-course', 'learn-press-global' ), 'LP_Settings' );
2169 }
2170 }
2171
2172 add_action( 'wp_print_scripts', 'learn_press_front_scripts' );*/
2173
2174 function learn_press_user_time( $time, $format = 'timestamp' ) {
2175 if ( is_string( $time ) ) {
2176 $time = @strtotime( $time );
2177 }
2178 $time = $time + ( get_option( 'gmt_offset' ) - $_COOKIE['timezone'] / 60 ) * HOUR_IN_SECONDS;
2179 switch ( $format ) {
2180 case 'timestamp':
2181 return $time;
2182 default:
2183 return date( 'Y-m-d H:i:s', $time );
2184 }
2185 }
2186
2187 function learn_press_get_current_version() {
2188 $data = get_plugin_data( LP_PLUGIN_FILE, $markup = true, $translate = true );
2189
2190 return $data['Version'];
2191 }
2192
2193 /**
2194 * Get current tab is displaying in user profile.
2195 * If there is no tab then get the first tab in
2196 * the list of tabs.
2197 *
2198 * @param bool $default
2199 *
2200 * @return mixed|string
2201 */
2202 function learn_press_get_current_profile_tab( $default = true ) {
2203 global $wp_query, $wp;
2204 $current = '';
2205
2206 if ( ! empty( $_REQUEST['tab'] ) ) {
2207 $current = LP_Helper::sanitize_params_submitted( $_REQUEST['tab'] );
2208 } elseif ( ! empty( $wp_query->query_vars['tab'] ) ) {
2209 $current = $wp_query->query_vars['tab'];
2210 } elseif ( ! empty( $wp->query_vars['view'] ) ) {
2211 $current = $wp->query_vars['view'];
2212 } else {
2213 $tabs = learn_press_get_user_profile_tabs();
2214 if ( $default && $tabs ) {
2215 // Fixed for array_keys does not work with ArrayAccess instance
2216 if ( $tabs instanceof LP_Profile_Tabs ) {
2217 $tabs = $tabs->tabs();
2218 }
2219
2220 $tab_keys = array_keys( $tabs );
2221 $current = reset( $tab_keys );
2222 }
2223 }
2224
2225 return $current;
2226 }
2227
2228 add_action( 'init', 'learn_press_get_current_profile_tab' );
2229
2230 function learn_press_profile_tab_exists( $tab ) {
2231 $tabs = learn_press_get_user_profile_tabs();
2232
2233 if ( $tabs ) {
2234 return ! empty( $tabs[ $tab ] ) ? true : false;
2235 }
2236
2237 return false;
2238 }
2239
2240 /**
2241 * Replace the spacing with the + (plus) char.
2242 *
2243 * @param string $string
2244 *
2245 * @return string
2246 */
2247 function _learn_press_urlencode( $string ) {
2248 return preg_replace( '/\s/', '+', $string );
2249 }
2250
2251 /**
2252 * Point the archive post type link to course page if current
2253 * post type is course and the page for displaying course is
2254 * setup.
2255 *
2256 * @param string $link
2257 * @param string $post_type
2258 *
2259 * @return string
2260 */
2261 function learn_press_post_type_archive_link( $link, $post_type ) {
2262 if ( $post_type == LP_COURSE_CPT && learn_press_get_page_id( 'courses' ) ) {
2263 $link = learn_press_get_page_link( 'courses' );
2264 }
2265
2266 return $link;
2267 }
2268
2269 add_filter( 'post_type_archive_link', 'learn_press_post_type_archive_link', 10, 2 );
2270
2271 function learn_press_single_term_title( $prefix = '', $display = true ) {
2272 $term = get_queried_object();
2273
2274 if ( ! $term ) {
2275 return '';
2276 }
2277
2278 if ( learn_press_is_course_category() ) {
2279 $term_name = apply_filters( 'single_course_category_title', $term->name );
2280 } elseif ( learn_press_is_course_tag() ) {
2281 $term_name = apply_filters( 'single_course_tag_title', $term->name );
2282 } elseif ( learn_press_is_course_taxonomy() ) {
2283 $term_name = apply_filters( 'single_course_term_title', $term->name );
2284 } else {
2285 return single_term_title( $prefix, $display );
2286 }
2287
2288 if ( empty( $term_name ) ) {
2289 return single_term_title( $prefix, $display );
2290 }
2291
2292 if ( $display ) {
2293 echo $prefix . $term_name;
2294 }
2295
2296 return $prefix . $term_name;
2297 }
2298
2299 /**
2300 * Control the template file if user is searching course.
2301 * Use the template of archive course to display the
2302 * result if there is a flag in request to search course.
2303 *
2304 * @param string $template
2305 *
2306 * @return string
2307 */
2308 function learn_press_search_template( $template ) {
2309 if ( ! empty( $_REQUEST['ref'] ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course' ) {
2310 $template = learn_press_locate_template( 'archive-course.php' );
2311 }
2312
2313 return $template;
2314 }
2315
2316 /**
2317 * Auto enroll user to a course after an order is completed
2318 * if the option auto-enroll is turn on.
2319 *
2320 * @param int $order_id
2321 *
2322 * @return mixed
2323 * @editor tungnx
2324 */
2325 function learn_press_auto_enroll_user_to_courses( $order_id ) {
2326 _deprecated_function( __FUNCTION__, '4.1.3' );
2327 }
2328
2329 // add_action( 'learn_press_order_status_completed', 'learn_press_auto_enroll_user_to_courses' );
2330
2331 /**
2332 * Return true if enable cart
2333 *
2334 * @return bool
2335 */
2336 function learn_press_is_enable_cart() {
2337 return defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART == true;
2338 }
2339
2340 /**
2341 * Short way to get checkout object
2342 *
2343 * @param array
2344 *
2345 * @return LP_Checkout
2346 */
2347 function learn_press_get_checkout( $args = null ) {
2348 $checkout = LP_Checkout::instance();
2349
2350 if ( is_array( $args ) ) {
2351 foreach ( $args as $k => $v ) {
2352 $checkout->{$k} = $v;
2353 }
2354 }
2355
2356 return $checkout;
2357 }
2358
2359 if ( defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART ) {
2360 add_filter( 'learn_press_checkout_settings', '_learn_press_cart_settings', 10, 2 );
2361 function _learn_press_cart_settings( $settings, $class ) {
2362 $settings = array_merge(
2363 $settings,
2364 array(
2365 array(
2366 'title' => __( 'Cart', 'learnpress' ),
2367 'type' => 'title',
2368 ),
2369 array(
2370 'title' => __( 'Enable cart', 'learnpress' ),
2371 'desc' => __(
2372 'Check this option to enable user purchase multiple courses at one time.',
2373 'learnpress'
2374 ),
2375 'id' => $class->get_field_name( 'enable_cart' ),
2376 'default' => 'yes',
2377 'type' => 'checkbox',
2378 ),
2379 array(
2380 'title' => __( 'Add to cart redirect', 'learnpress' ),
2381 'desc' => __( 'Redirect to checkout immediately after adding course to cart.', 'learnpress' ),
2382 'id' => $class->get_field_name( 'redirect_after_add' ),
2383 'default' => 'yes',
2384 'type' => 'checkbox',
2385 ),
2386 array(
2387 'title' => __( 'AJAX add to cart', 'learnpress' ),
2388 'desc' => __( 'Using AJAX to add course to cart.', 'learnpress' ),
2389 'id' => $class->get_field_name( 'ajax_add_to_cart' ),
2390 'default' => 'no',
2391 'type' => 'checkbox',
2392 ),
2393 array(
2394 'title' => __( 'Cart page', 'learnpress' ),
2395 'id' => $class->get_field_name( 'cart_page_id' ),
2396 'default' => '',
2397 'type' => 'pages-dropdown',
2398 ),
2399 )
2400 );
2401
2402 return $settings;
2403 }
2404 } else {
2405 add_filter( 'learn_press_enable_cart', '_learn_press_enable_cart', 1000 );
2406 function _learn_press_enable_cart( $r ) {
2407 return false;
2408 }
2409
2410 add_filter( 'learn_press_get_template', '_learn_press_enroll_button', 1000, 5 );
2411 function _learn_press_enroll_button( $located, $template_name, $args, $template_path, $default_path ) {
2412 if ( $template_name == 'single-course/enroll-button.php' ) {
2413 $located = learn_press_locate_template(
2414 'single-course/enroll-button-new.php',
2415 $template_path,
2416 $default_path
2417 );
2418 }
2419
2420 return $located;
2421 }
2422 }
2423
2424 /**
2425 * Returns checkout url from setting
2426 *
2427 * @return string
2428 */
2429 function learn_press_get_checkout_url() {
2430 $checkout_url = learn_press_get_page_link( 'checkout' );
2431
2432 return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
2433 }
2434
2435 /**
2436 * @return string
2437 */
2438 function learn_press_checkout_needs_payment() {
2439 return LP()->cart->needs_payment();
2440 }
2441
2442 /**
2443 * Return plugin basename
2444 *
2445 * @param string $filepath
2446 *
2447 * @return string
2448 */
2449 /*
2450 function learn_press_plugin_basename( $filepath ) {
2451 $file = str_replace( '\\', '/', $filepath );
2452 $file = preg_replace( '|/+|', '/', $file );
2453 $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR );
2454 $plugin_dir = preg_replace( '|/+|', '/', $plugin_dir );
2455 $mu_plugin_dir = str_replace( '\\', '/', WPMU_PLUGIN_DIR );
2456 $mu_plugin_dir = preg_replace( '|/+|', '/', $mu_plugin_dir );
2457 $sp_plugin_dir = dirname( $filepath );
2458 $sp_plugin_dir = dirname( $sp_plugin_dir );
2459 $sp_plugin_dir = str_replace( '\\', '/', $sp_plugin_dir );
2460 $sp_plugin_dir = preg_replace( '|/+|', '/', $sp_plugin_dir );
2461
2462 $file = preg_replace(
2463 '#^' . preg_quote( $sp_plugin_dir, '#' ) . '/|^' . preg_quote(
2464 $plugin_dir,
2465 '#'
2466 ) . '/|^' . preg_quote(
2467 $mu_plugin_dir,
2468 '#'
2469 ) . '/#',
2470 '',
2471 $file
2472 );
2473 $file = trim( $file, '/' );
2474
2475 return strtolower( $file );
2476 }*/
2477
2478 /**
2479 * Update log data for each LP version into wp option.
2480 *
2481 * @param string $version
2482 * @param mixed $data
2483 */
2484 function learn_press_update_log( $version, $data ) {
2485 $logs = get_option( 'learn_press_update_logs' );
2486 if ( ! $logs ) {
2487 $logs = array( $version => $data );
2488 } else {
2489 $logs[ $version ] = $data;
2490 }
2491 update_option( 'learn_press_update_logs', $logs );
2492 }
2493
2494 /**
2495 * Output variables to screen for debugging.
2496 */
2497 function learn_press_debug() {
2498 $args = func_get_args();
2499 $debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
2500
2501 echo '<pre>';
2502 print_r( $debug );
2503 $arg = false;
2504
2505 if ( $args ) {
2506 foreach ( $args as $arg ) {
2507 echo "\n======LearnPress Debug=======\n";
2508 print_r( $arg );
2509 echo "\n=============================\n";
2510 }
2511 }
2512 echo '</pre>';
2513
2514 if ( true === $arg ) {
2515 die( __FUNCTION__ );
2516 }
2517 }
2518
2519 /**
2520 * Get current time to user for calculate remaining time of quiz.
2521 *
2522 * @return int
2523 */
2524 function learn_press_get_current_time() {
2525 $current_time = apply_filters( 'learn_press_get_current_time', 0 );
2526
2527 if ( $current_time > 0 ) {
2528 return $current_time;
2529 }
2530
2531 $a = current_time( 'timestamp' );
2532 $b = time();
2533 $c = current_time( 'mysql' );
2534 $d = strtotime( $c );
2535
2536 if ( $d == $a ) {
2537 return $a;
2538 } else {
2539 return $b;
2540 }
2541 }
2542
2543 function learn_press_get_requested_post_type() {
2544 global $pagenow;
2545 if ( $pagenow == 'post-new.php' && ! empty( $_REQUEST['post_type'] ) ) {
2546 $post_type = LP_Helper::sanitize_params_submitted( $_REQUEST['post_type'] );
2547 } else {
2548 $post_id = learn_press_get_post();
2549 $post_type = learn_press_get_post_type( $post_id );
2550 }
2551
2552 return $post_type;
2553 }
2554
2555 /**
2556 * Get human string from grade slug.
2557 *
2558 * @param string $slug
2559 *
2560 * @return string
2561 */
2562 function learn_press_get_graduation_text( $slug ) {
2563 switch ( $slug ) {
2564 case 'passed':
2565 $text = esc_html__( 'Passed', 'learnpress' );
2566 break;
2567 case 'failed':
2568 $text = esc_html__( 'Failed', 'learnpress' );
2569 break;
2570 case 'in-progress':
2571 $text = esc_html__( 'In Progress', 'learnpress' );
2572 break;
2573 default:
2574 $text = $slug;
2575 }
2576
2577 return apply_filters( 'learn-press/get-graduation-text', $text, $slug );
2578 }
2579
2580 /*function learn_press_execute_time( $n = 1 ) {
2581 static $time;
2582 if ( empty( $time ) ) {
2583 $time = microtime( true );
2584
2585 return $time;
2586 } else {
2587 $execute_time = microtime( true ) - $time;
2588
2589 echo 'Execute time ' . $n * $execute_time . "\n";
2590 $time = 0;
2591
2592 return $execute_time;
2593 }
2594 }*/
2595
2596 if ( ! function_exists( 'learn_press_is_negative_value' ) ) {
2597 function learn_press_is_negative_value( $value ) {
2598 $return = in_array( $value, array( 'no', 'off', 'false', '0' ) ) || ! $value || $value == '' || $value == null;
2599
2600 return $return;
2601 }
2602 }
2603
2604 /**
2605 * Filter to comment reply link to fix bug the link is invalid for
2606 * lesson or quiz.
2607 *
2608 * @param string $link
2609 * @param array $args
2610 * @param WP_Comment $comment
2611 * @param WP_Post $post
2612 *
2613 * @return string
2614 */
2615 function learn_press_comment_reply_link( $link, $args = array(), $comment = null, $post = null ) {
2616
2617 $post_type = learn_press_get_post_type( $post );
2618
2619 if ( ! learn_press_is_support_course_item_type( $post_type ) ) {
2620 return $link;
2621 }
2622
2623 $course_item = LP_Global::course_item();
2624
2625 if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
2626 $link = sprintf(
2627 '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
2628 esc_url_raw( wp_login_url( get_permalink() ) ),
2629 $args['login_text']
2630 );
2631 } elseif ( $course_item ) {
2632 $onclick = sprintf(
2633 'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
2634 $args['add_below'],
2635 $comment->comment_ID,
2636 $args['respond_id'],
2637 $post->ID
2638 );
2639
2640 $link = sprintf(
2641 "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
2642 esc_url_raw(
2643 add_query_arg(
2644 array(
2645 'replytocom' => $comment->comment_ID,
2646 ),
2647 $course_item->get_permalink()
2648 )
2649 ) . '#' . $args['respond_id'],
2650 $onclick,
2651 esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
2652 $args['reply_text']
2653 );
2654 }
2655
2656 return $link;
2657 }
2658
2659 add_filter( 'comment_reply_link', 'learn_press_comment_reply_link', 10, 4 );
2660
2661 function learn_press_deprecated_function( $function, $version, $replacement = null ) {
2662 if ( LP_Debug::is_debug() ) {
2663 _deprecated_function( $function, $version, $replacement );
2664 }
2665 }
2666
2667
2668 /**
2669 * Sanitize content of tooltip
2670 *
2671 * @param string $tooltip
2672 * @param bool $html
2673 *
2674 * @return string
2675 */
2676 function learn_press_sanitize_tooltip( $tooltip, $html = false ) {
2677 if ( $html ) {
2678 $tooltip = htmlspecialchars(
2679 wp_kses(
2680 html_entity_decode( $tooltip ),
2681 array(
2682 'br' => array(),
2683 'em' => array(),
2684 'strong' => array(),
2685 'small' => array(),
2686 'span' => array(),
2687 'ul' => array(),
2688 'li' => array(),
2689 'ol' => array(),
2690 'p' => array(),
2691 )
2692 )
2693 );
2694 } else {
2695 $tooltip = esc_attr( $tooltip );
2696 }
2697
2698 return $tooltip;
2699 }
2700
2701 function learn_press_tooltip( $tooltip, $html = false ) {
2702 $tooltip = learn_press_sanitize_tooltip( $tooltip, $html );
2703 echo '<span class="learn-press-tooltip" data-tooltip="' . esc_attr( $tooltip ) . '"></span>';
2704 }
2705
2706 /**
2707 * Get timezone offset from wp settings.
2708 *
2709 * @return float|int
2710 * @since 3.0.0
2711 */
2712 function learn_press_timezone_offset() {
2713 if ( $tz = get_option( 'timezone_string' ) ) {
2714 $timezone = new DateTimeZone( $tz );
2715
2716 return $timezone->getOffset( new DateTime( 'now' ) );
2717 } else {
2718 return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS;
2719 }
2720 }
2721
2722 /**
2723 * Get default static pages of LP.
2724 *
2725 * @return array
2726 *
2727 * @since 3.0.0
2728 */
2729 function learn_press_static_page_ids() {
2730 $pages = LP_Object_Cache::get( 'static-page-ids', 'learn-press' );
2731
2732 if ( false === $pages ) {
2733 $pages = array(
2734 'checkout' => learn_press_get_page_id( 'checkout' ),
2735 'courses' => learn_press_get_page_id( 'courses' ),
2736 'profile' => learn_press_get_page_id( 'profile' ),
2737 'become_a_teacher' => learn_press_get_page_id( 'become_a_teacher' ),
2738 );
2739
2740 foreach ( $pages as $name => $id ) {
2741 if ( ! get_post( $id ) ) {
2742 $pages[ $name ] = 0;
2743 }
2744 }
2745
2746 LP_Object_Cache::set( 'static-page-ids', $pages, 'learn-press' );
2747 }
2748
2749 return apply_filters( 'learn-press/static-page-ids', $pages );
2750 }
2751
2752 /**
2753 * Get default static pages of LP.
2754 *
2755 * @param bool $name - Optional. TRUE will return name only.
2756 *
2757 * @return array
2758 *
2759 * @since 3.0.0
2760 */
2761 function learn_press_static_pages( $name = false ) {
2762 $pages = apply_filters(
2763 'learn-press/static-pages',
2764 array(
2765 'checkout' => _x( 'Checkout', 'static-page-name', 'learnpress' ),
2766 'courses' => _x( 'Courses', 'static-page-name', 'learnpress' ),
2767 'profile' => _x( 'Profile', 'static-page-name', 'learnpress' ),
2768 'become_a_teacher' => _x( 'Become a Teacher', 'static-page-name', 'learnpress' ),
2769 )
2770 );
2771
2772 if ( $name ) {
2773 return array_keys( $pages );
2774 }
2775
2776 return $pages;
2777 }
2778
2779 /*function learn_press_cache_path( $group, $key = '' ) {
2780 $path = LP_PLUGIN_PATH . 'cache';
2781 if ( ! file_exists( $path ) ) {
2782 @mkdir( $path );
2783 }
2784 $path = $path . '/' . $group;
2785
2786 if ( ! file_exists( $path ) ) {
2787 @mkdir( $path );
2788 }
2789 if ( $key ) {
2790 $path = $path . '/' . $key . '.ch';
2791 }
2792
2793 return $path;
2794 }*/
2795
2796 function learn_press_cache_get( $key, $group, $found = null ) {
2797 //$file = learn_press_cache_path( $group, $key );
2798 $data = wp_cache_get( $key, $group, $found );
2799
2800 /*if ( ! file_exists( $file ) ) {
2801 return false;
2802 }*/
2803
2804 /*if ( false === $data ) {
2805 $content = file_get_contents( $file );
2806
2807 if ( file_exists( $file ) && $content ) {
2808 try {
2809 $data = unserialize( $content );
2810 } catch ( Exception $ex ) {
2811 print_r( $content );
2812 die();
2813 }
2814 wp_cache_set( $key, $data, $group, $found );
2815 }
2816 }*/
2817
2818 return $data;
2819 }
2820
2821 function learn_press_cache_set( $key, $data, $group = '', $expire = 0 ) {
2822 //$file = learn_press_cache_path( $group, $key );
2823 wp_cache_set( $key, $data, $group, $expire );
2824
2825 /*if ( ! is_string( $data ) ) {
2826 $data = serialize( $data );
2827 }
2828 file_put_contents( $file, $data );*/
2829 }
2830
2831 function learn_press_cache_replace( $key, $data, $group = '', $expire = 0 ) {
2832 wp_cache_replace( $key, $data, $group, $expire );
2833 }
2834
2835 function learn_press_cache_add( $key, $data, $group = '', $expire = 0 ) {
2836 wp_cache_add( $key, $data, $group, $expire );
2837 }
2838
2839 if ( ! function_exists( 'learn_press_get_widget_course_object' ) ) {
2840 /**
2841 * Get course object for widget query.
2842 *
2843 * @param $query
2844 *
2845 * @return array
2846 * @deprecated v4.1.6.1 - we will remove on the version 4.1.7
2847 */
2848 function learn_press_get_widget_course_object( $query ) {
2849
2850 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2851
2852 global $wpdb;
2853
2854 $posts = $wpdb->get_results( $query );
2855 if ( $posts ) {
2856 // get lp courses object from WordPress post
2857 $courses = array_map( 'learn_press_get_lp_course', $posts );
2858 $courses = array_filter( $courses );
2859
2860 } else {
2861 $courses = array();
2862 }
2863
2864 return $courses;
2865 }
2866 }
2867
2868 if ( ! function_exists( 'learn_press_get_lp_course' ) ) {
2869 /**
2870 * Get learn press course from WordPress post object
2871 *
2872 * @param object - reference $post WordPress post object
2873 *
2874 * @return LP_Course course
2875 * @deprecated v4.1.6.1 - we will remove on the version 4.1.7
2876 */
2877 function learn_press_get_lp_course( $post ) {
2878 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2879
2880 $id = $post->ID;
2881 $course = null;
2882 if ( ! empty( $id ) ) {
2883 // $course = new LP_Course( $id );
2884 $course = learn_press_get_course( $id );
2885 }
2886
2887 return $course;
2888 }
2889 }
2890
2891 /**
2892 * Get all items are unassigned to any course.
2893 *
2894 * @param string|array $type - Optional. Types of items to get, default is all.
2895 *
2896 * @return array
2897 * @since 3.0.0
2898 * @deprecated 4.1.4.1 - Will remove on version 4.1.7
2899 */
2900 function learn_press_get_unassigned_items( $type = '' ) {
2901 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2902
2903 global $wpdb;
2904
2905 if ( ! $type ) {
2906 $type = learn_press_course_get_support_item_types();
2907 $type = array_keys( $type );
2908 }
2909
2910 settype( $type, 'array' );
2911 $key = 'items-' . md5( serialize( $type ) );
2912
2913 if ( false === ( $items = LP_Object_Cache::get( $key, 'learn-press/unassigned' ) ) ) {
2914 $format = array_fill( 0, sizeof( $type ), '%s' );
2915
2916 $query = $wpdb->prepare(
2917 "
2918 SELECT p.ID
2919 FROM {$wpdb->posts} p
2920 WHERE p.post_type IN(" . join( ',', $format ) . ")
2921 AND p.ID NOT IN(
2922 SELECT si.item_id
2923 FROM {$wpdb->learnpress_section_items} si
2924 INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
2925 WHERE p.post_type IN(" . join( ',', $format ) . ')
2926 )
2927 AND p.post_status NOT IN(%s, %s)
2928 ',
2929 array_merge( $type, $type, array( 'auto-draft', 'trash' ) )
2930 );
2931
2932 $items = $wpdb->get_col( $query );
2933
2934 //LP_Debug::var_dump($query, __FILE__, __LINE__);
2935
2936 LP_Object_Cache::set( $key, $items, 'learn-press/unassigned' );
2937 }
2938
2939 return $items;
2940 }
2941
2942 /**
2943 * Get all questions are unassigned to any quiz.
2944 *
2945 * @return array
2946 * @since 3.0.0
2947 * @deprecated 4.1.6.1 - Will remove on version 4.1.7
2948 */
2949 function learn_press_get_unassigned_questions() {
2950 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2951
2952 global $wpdb;
2953
2954 if ( false === ( $questions = LP_Object_Cache::get( 'questions', 'learn-press/unassigned' ) ) ) {
2955 $query = $wpdb->prepare(
2956 "
2957 SELECT p.ID
2958 FROM {$wpdb->posts} p
2959 WHERE p.post_type = %s
2960 AND p.ID NOT IN(
2961 SELECT qq.question_id
2962 FROM {$wpdb->learnpress_quiz_questions} qq
2963 INNER JOIN {$wpdb->posts} p ON p.ID = qq.question_id
2964 WHERE p.post_type = %s
2965 )
2966 AND p.post_status NOT IN(%s, %s)
2967 ",
2968 LP_QUESTION_CPT,
2969 LP_QUESTION_CPT,
2970 'auto-draft',
2971 'trash'
2972 );
2973
2974 $questions = $wpdb->get_col( $query );
2975 LP_Object_Cache::set( 'questions', $questions, 'learn-press/unassigned' );
2976 }
2977
2978 return $questions;
2979 }
2980
2981 /**
2982 * Callback function for sorting to array|object by key|prop priority.
2983 *
2984 * @param array|object $a
2985 * @param array|object $b
2986 *
2987 * @return int
2988 * @since 3.0.0
2989 */
2990 function learn_press_sort_list_by_priority_callback( $a, $b ) {
2991 $a_priority = null;
2992 $b_priority = null;
2993
2994 if ( is_array( $a ) && array_key_exists( 'priority', $a ) ) {
2995 $a_priority = $a['priority'];
2996 } elseif ( is_object( $a ) ) {
2997 if ( is_callable( array( $a, 'get_priority' ) ) ) {
2998 $a_priority = $a->get_priority();
2999 } elseif ( property_exists( $a, 'priority' ) ) {
3000 $a_priority = $a->priority;
3001 }
3002 }
3003
3004 if ( is_array( $b ) && array_key_exists( 'priority', $b ) ) {
3005 $b_priority = $b['priority'];
3006 } elseif ( is_object( $b ) ) {
3007 if ( is_callable( array( $b, 'get_priority' ) ) ) {
3008 $b_priority = $b->get_priority();
3009 } elseif ( property_exists( $b, 'priority' ) ) {
3010 $b_priority = $b->priority;
3011 }
3012 }
3013
3014 if ( $a_priority === $b_priority ) {
3015 return 0;
3016 }
3017
3018 return ( $a_priority < $b_priority ) ? - 1 : 1;
3019 }
3020
3021 /**
3022 * Localize date with custom format.
3023 *
3024 * @param string $timestamp
3025 * @param string $format
3026 * @param bool $gmt
3027 *
3028 * @return string
3029 * @since 3.0.0
3030 */
3031 function learn_press_date_i18n( $timestamp = '', $format = '', $gmt = false ) {
3032 if ( ! $format ) {
3033 $format = get_option( 'date_format' );
3034 }
3035
3036 return date_i18n( $format, $timestamp, $gmt );
3037 }
3038
3039 function learn_press_date() {
3040
3041 }
3042
3043 /**
3044 * Remove user items.
3045 *
3046 * @param int $item_id
3047 * @param int $course_id
3048 * @param int $user_id
3049 * @param int $keep
3050 *
3051 * @since 3.0.8
3052 * @deprecated 4.1.6.1 - Will remove on version 4.1.7
3053 */
3054 function learn_press_remove_user_items_history( $item_id, $course_id, $user_id, $keep = 10 ) {
3055 _deprecated_function( __FUNCTION__, '4.1.6.1' );
3056
3057 $user = learn_press_get_user( $user_id );
3058 if ( $rows = $user->get_item_archive( $item_id, $course_id ) ) {
3059
3060 global $wpdb;
3061
3062 $args = array( $user_id, $item_id, $course_id );
3063 $query = $wpdb->prepare(
3064 "
3065 DELETE
3066 FROM {$wpdb->learnpress_user_items}
3067 WHERE user_id = %d AND item_id = %d
3068 AND ref_id = %d
3069 ",
3070 $args
3071 );
3072
3073 if ( $keep ) {
3074 $user_item_ids = array_keys( $rows );
3075 $user_item_ids = array_splice( $user_item_ids, 0, $keep );
3076 $format = array_fill( 0, sizeof( $user_item_ids ), '%d' );
3077
3078 $query .= $wpdb->prepare( ' AND user_item_id NOT IN(' . join( ',', $format ) . ')', $user_item_ids );
3079 }
3080
3081 $wpdb->query( $query );
3082 }
3083 }
3084
3085 /**
3086 * Get item types of course support for blocking. Default is lp_lesson
3087 *
3088 * @return array
3089 * @since 3.0.0
3090 */
3091 function learn_press_get_block_course_item_types() {
3092 return apply_filters( 'learn-press/block-course-item-types', array( LP_LESSON_CPT, LP_QUIZ_CPT ) );
3093 }
3094
3095 /**
3096 * Get post type of a post from cache.
3097 * If there is no data stored in cache then
3098 * get it from WP API.
3099 *
3100 * @param int|WP_Post $post
3101 *
3102 * @return string
3103 * @since 3.1.0
3104 */
3105 function learn_press_get_post_type( $post ) {
3106 $post_types = LP_Object_Cache::get( 'post-types', 'learn-press' );
3107
3108 if ( false === $post_types ) {
3109 $post_types = array();
3110 }
3111
3112 if ( is_object( $post ) ) {
3113 $post_id = $post->ID;
3114 } else {
3115 $post_id = absint( $post );
3116 }
3117
3118 if ( empty( $post_types[ $post_id ] ) ) {
3119 $post_type = get_post_type( $post_id );
3120 $post_types[ $post_id ] = $post_type;
3121 LP_Object_Cache::set( 'post-types', $post_types, 'learn-press' );
3122 } else {
3123 $post_type = $post_types[ $post_id ];
3124 }
3125
3126 return $post_type;
3127 }
3128
3129 /**
3130 * Add post type of a post into cache
3131 *
3132 * @param int|array $id
3133 * @param string $type
3134 *
3135 * @since 3.1.0
3136 */
3137 function learn_press_cache_add_post_type( $id, $type = '' ) {
3138 if ( false === ( $post_types = LP_Object_Cache::get( 'post-types', 'learn-press' ) ) ) {
3139 $post_types = array();
3140 }
3141
3142 if ( func_num_args() == 1 && is_array( $id ) ) {
3143 $post_types = $post_types + $id;
3144 } else {
3145 $post_types[ $id ] = $type;
3146 }
3147
3148 LP_Object_Cache::set( 'post-types', $post_types, 'learn-press' );
3149 }
3150
3151 function learn_press_has_option( $name ) {
3152 global $wpdb;
3153
3154 $query = $wpdb->prepare( "SELECT option_id FROM {$wpdb->options} WHERE option_name = %s", $name );
3155
3156 return $wpdb->get_var( $query ) > 0;
3157 }
3158
3159 /**
3160 * Update option to enable shuffle themes for ad.
3161 *
3162 * @since 3.2.1
3163 */
3164 function _learn_press_schedule_enable_shuffle_themes() {
3165 update_option( 'learn_press_ad_shuffle_themes', 'yes' );
3166 }
3167
3168 add_action( 'learn-press/schedule-enable-shuffle-themes', '_learn_press_schedule_enable_shuffle_themes' );
3169
3170 function learn_press_show_log() {
3171 if ( trim( LP_Request::get( 'show_log' ) ) === md5( AUTH_KEY ) ) {
3172 call_user_func_array( 'learn_press_debug', func_get_args() );
3173 }
3174 }
3175
3176 /**
3177 * @return array
3178 * @since 3.2.6
3179 */
3180 function learn_press_global_script_params() {
3181 $js = array(
3182 'ajax' => admin_url( 'admin-ajax.php' ),
3183 'plugin_url' => LP()->plugin_url(),
3184 'siteurl' => home_url(),
3185 'current_url' => learn_press_get_current_url(),
3186 'theme' => get_stylesheet(),
3187 'localize' => array(
3188 'button_ok' => __( 'OK', 'learnpress' ),
3189 'button_cancel' => __( 'Cancel', 'learnpress' ),
3190 'button_yes' => __( 'Yes', 'learnpress' ),
3191 'button_no' => __( 'No', 'learnpress' ),
3192 ),
3193 'root' => esc_url_raw( rest_url() ),
3194 'nonce' => wp_create_nonce( 'wp_rest' ),
3195 );
3196
3197 return $js;
3198 }
3199
3200 /**
3201 * Get url for setup cron job on server.
3202 *
3203 * @return string
3204 * @since 3.3.0
3205 */
3206 function learn_press_get_cron_url() {
3207 $nonce = get_option( 'learnpress_cron_url_nonce' );
3208
3209 if ( ! $nonce ) {
3210 $nonce = md5( microtime( true ) );
3211 update_option( 'learnpress_cron_url_nonce', $nonce );
3212 }
3213 $url = add_query_arg(
3214 array(
3215 'lp-ajax' => 'cron',
3216 'sid' => $nonce,
3217 ),
3218 get_home_url()
3219 );
3220
3221 return $url;
3222 }
3223
3224 /**
3225 * Get courses expired.
3226 *
3227 * @return array
3228 * @since 3.3.0
3229 */
3230 function learn_press_get_expired_courses() {
3231 global $wpdb;
3232
3233 $query = $wpdb->prepare(
3234 "
3235 SELECT X.*
3236 FROM(
3237 SELECT ui.*
3238 FROM {$wpdb->learnpress_user_items} ui
3239 LEFT JOIN {$wpdb->learnpress_user_items} uix
3240 ON ui.item_id = uix.item_id
3241 AND ui.user_id = uix.user_id
3242 AND ui.user_item_id < uix.user_item_id
3243 WHERE uix.user_item_id IS NULL
3244 ) X
3245 INNER JOIN {$wpdb->users} u ON u.ID = X.user_id
3246 INNER JOIN {$wpdb->posts} p ON p.ID = X.item_id
3247 WHERE X.item_type = %s
3248 AND X.status = %s
3249 #AND expiration_time_gmt <= UTC_TIMESTAMP()
3250 AND expiration_time <= UTC_TIMESTAMP()
3251 LIMIT 0, 10
3252 ",
3253 LP_COURSE_CPT,
3254 'enrolled'
3255 );
3256
3257 }
3258
3259 /**
3260 * Add new error log. Support message as an array|object.
3261 * Convert message to string if it is not a string.
3262 *
3263 * @param mixed $value
3264 *
3265 * @since 4.0.0
3266 */
3267 function learn_press_error_log( $value ) {
3268 if ( is_array( $value ) || is_object( $value ) ) {
3269 ob_start();
3270 print_r( $value );
3271 $value = ob_get_clean();
3272 }
3273
3274 error_log( $value );
3275 }
3276
3277 /**
3278 * Get status of global course for current user.
3279 *
3280 * @param int $user_id
3281 * @param int $course_id
3282 *
3283 * @return bool|string
3284 * @since 3.3.0
3285 * @editor tungnx
3286 * @modify 4.1.3 - comment - not use
3287 */
3288 /*function learn_press_user_course_status( $user_id = 0, $course_id = 0 ) {
3289 if ( ! $user = learn_press_get_user( $user_id ? $user_id : get_current_user_id() ) ) {
3290 return false;
3291 }
3292
3293 if ( ! $userCourse = $user->get_course_data( $course_id ) ) {
3294 return false;
3295 }
3296
3297 return $userCourse->get_status();
3298 }*/
3299
3300 /**
3301 * Return list types of questions that support answer options.
3302 *
3303 * @return array
3304 * @since 3.3.0
3305 */
3306 function learn_press_get_question_support_answer_options() {
3307 $questions = learn_press_get_question_support_feature( 'answer-options' );
3308
3309 return apply_filters( 'learn-press/questions-support-answer-options', $questions );
3310 }
3311
3312 /**
3313 * Return list types of question that support a feature.
3314 *
3315 * @param string $feature
3316 *
3317 * @return array
3318 * @since 3.3.0
3319 */
3320 function learn_press_get_question_support_feature( $feature ) {
3321 $questions = array();
3322 $types = LP_Global::get_object_supports( 'question' );
3323
3324 if ( $types ) {
3325 foreach ( $types as $type => $features ) {
3326 if ( array_key_exists( $feature, $features ) ) {
3327 $questions[] = $type;
3328 }
3329 }
3330 }
3331
3332 return $questions;
3333 }
3334
3335 /**
3336 * Helper function to output html for rendering a 'circle progress bar'
3337 *
3338 * @param int $percent
3339 * @param int $width
3340 * @param int $border
3341 * @param string $color
3342 *
3343 * @since 3.3.0
3344 */
3345 function learn_press_circle_progress_html( $percent = 0, $width = 32, $border = 4, $color = '' ) {
3346 $radius = $width / 2;
3347 $r = ( $width - $border ) / 2;
3348 $circumference = $r * 2 * pi();
3349 $offset = $circumference - $percent / 100 * $circumference;
3350
3351 printf(
3352 '<svg class="circle-progress-bar" width="%d" height="%d">
3353 <circle class="circle-progress-bar__circle"
3354 stroke="%s"
3355 stroke-width="%d"
3356 style="stroke-dasharray:%s %s; stroke-dashoffset:%s;"
3357 fill="transparent"
3358 r="%d" cx="%d" cy="%d"></circle>
3359 </svg>',
3360 $width,
3361 $width,
3362 $color,
3363 $border,
3364 $circumference,
3365 $circumference,
3366 $offset,
3367 $r,
3368 $radius,
3369 $radius
3370 );
3371 }
3372
3373 function learn_press_is_page( $page_name ) {
3374 $page_id = learn_press_get_page_id( $page_name );
3375
3376 return $page_id && is_page( $page_id );
3377 }
3378
3379 /**
3380 * Get end-date from start date with a duration.
3381 *
3382 * @param string|int $duration
3383 * @param string|int $start
3384 *
3385 * @return false|string
3386 * @since 3.x.x
3387 */
3388 function learn_press_date_end_from( $duration, $start = '' ) {
3389 $format = 'Y-m-d H:i:s';
3390
3391 if ( ! $start ) {
3392 $start = time();
3393 } elseif ( ! is_numeric( $start ) ) {
3394 $start = strtotime( $start );
3395 }
3396
3397 // is LP duration format, e.g: 10 weeks
3398 if ( preg_match( '/^[0-9]+ [a-z]+$/', $duration ) ) {
3399 $duration = ( new LP_Duration( $duration ) )->get();
3400 } elseif ( ! is_numeric( $duration ) ) {
3401 // 10 days 5 hours ...
3402 $duration = strtotime( $duration, 0 );
3403 }
3404
3405 return date( $format, $start + $duration );
3406 }
3407
3408 function learn_press_date_diff( $from, $to ) {
3409
3410 }
3411
3412 function learn_press_cookie_get( $name, $namespace = 'LP' ) {
3413 if ( $namespace ) {
3414 $cookie = ! empty( $_COOKIE[ $namespace ] ) ? (array) json_decode( LP_Helper::sanitize_params_submitted( stripslashes( $_COOKIE[ $namespace ] ), 'html' ) ) : array();
3415 } else {
3416 $cookie = $_COOKIE;
3417 }
3418
3419 return $cookie[ $name ] ?? null;
3420 }
3421
3422 /**
3423 * Get list of levels support in course.
3424 *
3425 * @return array
3426 * @since 3.x.x
3427 * @editor tungnx
3428 * @reason comment - not use
3429 */
3430 /*
3431 function learn_press_default_course_levels() {
3432 $levels = array(
3433 'beginner' => __( 'Beginner', 'learnpress' ),
3434 'intermediate' => __( 'Intermediate', 'learnpress' ),
3435 'expert' => __( 'Expert', 'learnpress' ),
3436 '' => __( 'All levels', 'learnpress' ),
3437 );
3438
3439 return apply_filters( 'learn-press/default-course-levels', $levels );
3440 }*/
3441
3442 /**
3443 * Get default methods to evaluate course results.
3444 *
3445 * @param string $return - Optional. 'keys' will return keys instead of all.
3446 *
3447 * @return array
3448 * @since 3.x.x
3449 */
3450 function learn_press_course_evaluation_methods( $postid, $return = '', $final_quizz_passing = '' ) {
3451 $course_tip = '<span class="learn-press-tip">%s</span>';
3452 $final_quiz_btn = '<a href="#" class="lp-metabox-get-final-quiz" data-postid="' . $postid . '" data-loading="' . esc_attr__(
3453 'Loading...',
3454 'learnpress'
3455 ) . '">' . esc_html__( 'Get Passing Grade', 'learnpress' ) . '</a>';
3456
3457 $course_desc = array(
3458 'evaluate_lesson' => sprintf(
3459 '<p>%s<br/>%s</p>',
3460 __( 'Evaluate by the number of lessons completed per total number of lessons.', 'learnpress' ),
3461 __( 'E.g: Course has 10 lessons and user completed 5 lessons then the result = 5/10 (50.%)', 'learnpress' )
3462 ),
3463 'evaluate_final_quiz' => __(
3464 'Evaluate by result of final quiz in the course. You have to add a quiz to the end of the course.',
3465 'learnpress'
3466 ),
3467 'evaluate_quiz' => sprintf(
3468 '<p>%s<br/>%s</p>',
3469 __( 'Evaluate by the number of quizzes passed per total number of quizzes.', 'learnpress' ),
3470 __(
3471 'E.g: The course has 10 quizzes and the user passed 5 quizzes then the result = 5/10 (50%).',
3472 'learnpress'
3473 )
3474 ),
3475 'evaluate_questions' => sprintf(
3476 '<p>%s<br/>%s</p>',
3477 __( 'Evaluate by total number of correct answers per total number of questions.', 'learnpress' ),
3478 __(
3479 'E.g: Course has 10 questions. User correct 5 questions. Result is 5/10 (50%).',
3480 'learnpress'
3481 )
3482 ),
3483 'evaluate_mark' => __( 'Evaluate by total score achieved per total score of the questions.', 'learnpress' ),
3484 );
3485
3486 $methods = apply_filters(
3487 'learnpress/course-evaluation/methods',
3488 array(
3489 'evaluate_lesson' => __(
3490 'Evaluate via lessons',
3491 'learnpress'
3492 ) . learn_press_quick_tip( $course_desc['evaluate_lesson'], false ),
3493 'evaluate_final_quiz' => __( 'Evaluate via results of the final quiz', 'learnpress' ) . sprintf(
3494 $course_tip,
3495 $course_desc['evaluate_final_quiz']
3496 ) . $final_quiz_btn . $final_quizz_passing,
3497 'evaluate_quiz' => __( 'Evaluate via quizzes passed', 'learnpress' ) . sprintf(
3498 $course_tip,
3499 $course_desc['evaluate_quiz']
3500 ),
3501 'evaluate_questions' => __( 'Evaluate via questions', 'learnpress' ) . sprintf(
3502 $course_tip,
3503 $course_desc['evaluate_questions']
3504 ),
3505 'evaluate_mark' => __( 'Evaluate via mark', 'learnpress' ) . sprintf(
3506 $course_tip,
3507 $course_desc['evaluate_mark']
3508 ),
3509 )
3510 );
3511
3512 return apply_filters(
3513 'learn-press/course-evaluation-methods',
3514 $return === 'keys' ? array_keys( $methods ) : $methods,
3515 $return
3516 );
3517 }
3518
3519 /**
3520 * Wrap WP Core function current_time with mysql format.
3521 *
3522 * @param bool $gmt
3523 *
3524 * @return int|string
3525 * @since 4.0.0
3526 * @editor tungnx
3527 * @modify 4.1.4.1 - comment - not use
3528 */
3529 /*function learn_press_mysql_time( $gmt = true ) {
3530 return current_time( 'mysql', $gmt );
3531 }*/
3532
3533 /**
3534 * Wrap WP Core function current_time with timestamp format.
3535 *
3536 * @param bool $gmt
3537 *
3538 * @return int|string
3539 * @since 4.0.0
3540 */
3541 function learn_press_timestamp( $gmt = true ) {
3542 return current_time( 'timestamp', $gmt );
3543 }
3544
3545 /**
3546 * Convert time from GMT to local.
3547 *
3548 * @param string|int|LP_Datetime $gmt_time
3549 * @param string $format
3550 *
3551 * @return false|int|string
3552 * @since 4.0.0
3553 */
3554 function learn_press_time_from_gmt( $gmt_time, $format = 'Y-m-d H:i:s' ) {
3555 if ( is_string( $gmt_time ) ) {
3556 $gmt_time = strtotime( $gmt_time );
3557 } elseif ( $gmt_time instanceof LP_Datetime ) {
3558 $gmt_time = strtotime( $gmt_time . '' );
3559 }
3560
3561 $current_time = $gmt_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
3562
3563 if ( $format ) {
3564 return date( $format, $current_time );
3565 }
3566
3567 return $current_time;
3568 }
3569
3570 /**
3571 * Count all users has enrolled courses of an instructor.
3572 *
3573 * @param int $instructor_id . Author of course
3574 *
3575 SELECT COUNT(DISTINCT (user_id)) AS total
3576 FROM wp_learnpress_user_items
3577 WHERE 1 = 1
3578 AND item_type = 'lp_course'
3579 AND item_id IN (
3580 SELECT ID
3581 FROM wp_posts
3582 WHERE post_author = 1
3583 AND post_type = 'lp_course'
3584 AND post_status = 'publish'
3585 );
3586 *
3587 * @return int
3588 * @since 4.0.0
3589 * @editor tungnx
3590 * @version 1.0.1
3591 * @deprecated 4.1.6 replace to "get_statistic_info" function
3592 */
3593 //function learn_press_count_instructor_users( int $instructor_id = 0 ): int {
3594 // try {
3595 // $filter_course = new LP_Course_Filter();
3596 // $filter_course->only_fields = array( 'ID' );
3597 // $filter_course->post_author = $instructor_id;
3598 // $filter_course->post_status = 'publish';
3599 // $filter_course->return_string_query = true;
3600 // $query_courses_str = LP_Course_DB::getInstance()->get_courses( $filter_course );
3601 //
3602 // $filter = new LP_User_Items_Filter();
3603 // $filter->only_fields = array( 'DISTINCT (ui.user_id)' );
3604 // $filter->field_count = 'DISTINCT (ui.user_id)';
3605 // $filter->where[] = "AND item_id IN ({$query_courses_str})";
3606 // $filter->query_count = true;
3607 //
3608 // return LP_User_Item_Course::get_user_courses( $filter );
3609 // //return LP_User_Items_DB::getInstance()->get_user_courses( $filter );
3610 // } catch ( Throwable $e ) {
3611 // error_log( __FUNCTION__ . ': ' . $e->getMessage() );
3612 //
3613 // return 0;
3614 // }
3615 //
3616 // /*$curd = new LP_User_CURD();
3617 // $own_courses = $curd->query_own_courses( $instructor_id );
3618 // $course_ids = $own_courses->get_items();*/
3619 //
3620 // /*
3621 // global $wpdb;
3622 // $filter = new LP_Course_Filter();
3623 // $filter->post_author = $instructor_id;
3624 // $filter->limit = -1;
3625 // $courses = LP_Course::get_courses( $filter );
3626 // $course_ids = LP_Course::get_course_ids( $courses );
3627 //
3628 // if ( ! empty( $course_ids ) ) {
3629 // $query = $wpdb->prepare(
3630 // "
3631 // SELECT COUNT(user_id)
3632 // FROM (
3633 // SELECT item_id, user_id
3634 // FROM {$wpdb->learnpress_user_items}
3635 // WHERE item_type = %s
3636 // GROUP BY item_id, user_id
3637 // HAVING item_id IN(" . join( ',', $course_ids ) . ')
3638 // ) X
3639 // GROUP BY item_id
3640 // ',
3641 // LP_COURSE_CPT
3642 // );
3643 //
3644 // $rows = $wpdb->get_col( $query );
3645 //
3646 // if ( $rows ) {
3647 // return array_sum( $rows );
3648 // }
3649 // }
3650 //
3651 // return 0;*/
3652 //}
3653
3654 /**
3655 * Get max retrying quiz allowed.
3656 *
3657 * @param int $quiz_id
3658 * @param int $course_id
3659 *
3660 * @return int
3661 * @since 4.0.0
3662 */
3663 function learn_press_get_quiz_max_retrying( $quiz_id = 0, $course_id = 0 ) {
3664 return apply_filters( 'learn-press/max-retry-quiz-allowed', 1, $quiz_id, $course_id );
3665 }
3666
3667 /**
3668 * Get max retrying course allowed.
3669 *
3670 * @param int $course_id
3671 *
3672 * @return int
3673 * @since 4.0.0
3674 */
3675 function learn_press_get_course_max_retrying( $course_id ) {
3676 return apply_filters( 'learn-press/max-retry-course-allowed', 1, $course_id );
3677 }
3678
3679 /**
3680 * Get slug for status of course/lesson/quiz if user
3681 * completed/finished and graduation is failed.
3682 *
3683 * @param string $type
3684 *
3685 * @return string
3686 * @since 4.0.0
3687 */
3688 function learn_press_user_item_failed_slug( $type = '' ) {
3689 return apply_filters( 'learn-press/user-item-failed-slug', 'failed', $type );
3690 }
3691
3692 /**
3693 * Get slug for status of course/lesson/quiz if user
3694 * completed/finished and graduation is passed.
3695 *
3696 * @param string $type
3697 *
3698 * @return string
3699 * @since 4.0.0
3700 */
3701 function learn_press_user_item_passed_slug( $type = '' ) {
3702 return apply_filters( 'learn-press/user-item-passed-slug', 'passed', $type );
3703 }
3704
3705 /**
3706 * Get slug for status of course/lesson/quiz if user
3707 * completed/finished and graduation is passed.
3708 *
3709 * @param string $type
3710 *
3711 * @return string
3712 * @since 4.0.0
3713 */
3714 function learn_press_user_item_in_progress_slug( $type = '' ) {
3715 return apply_filters( 'learn-press/user-item-in-progress-slug', 'in-progress', $type );
3716 }
3717
3718 /**
3719 * Get slug for status of course/lesson/quiz if user
3720 * completed/finished and result is under-evaluation
3721 *
3722 * @param string $item - Optional. Type of item
3723 *
3724 * @return string
3725 * @since 4.0.0
3726 */
3727 function learn_press_user_item_under_evaluation_slug( $item = '' ) {
3728 return apply_filters( 'learn-press/user-item-under-evaluation-slug', 'in-progress', $item );
3729 }
3730
3731 function learn_press_is_enrolled_slug( $slug ) {
3732 return in_array(
3733 $slug,
3734 array(
3735 'in-progress',
3736 'enrolled',
3737 )
3738 );
3739 }
3740
3741 /**
3742 * @return array
3743 * @since 4.0.0
3744 * @editor tungnx
3745 * @modify 4.1.3 - comment - not use
3746 */
3747 function learn_press_course_enrolled_slugs(): array {
3748 _deprecated_function( __FUNCTION__, '4.1.3' );
3749 return apply_filters(
3750 'learn-press/course-enrolled-slugs',
3751 array(
3752 learn_press_user_item_passed_slug(),
3753 learn_press_user_item_failed_slug(),
3754 'in-progress',
3755 'enrolled',
3756 'finished', // deprecated
3757 )
3758 );
3759 }
3760
3761 /**
3762 * @return array
3763 * @since 4.0.0
3764 */
3765 function lp_item_course_class( $class = array() ) {
3766 $classes = array_merge(
3767 $class,
3768 array( 'learn-press-courses' )
3769 );
3770 echo 'class="' . esc_attr( implode( ' ', apply_filters( 'lp_item_course_class', $classes ) ) ) . '"';
3771 }
3772
3773 //require_once dirname( __FILE__ ) . '/lp-custom-hooks.php';
3774
3775
3776 /**
3777 * Disable auto update
3778 *
3779 * @param $update
3780 * @param $item
3781 *
3782 * @return false
3783 * @author hungkv
3784 */
3785 /*function learnpress_disable_auto_update( $update, $item ) {
3786 $plugins = array( // Plugins to auto-update
3787 'learnpress',
3788 );
3789 // Auto-update specified plugins
3790 if ( in_array( $item->slug, $plugins ) ) {
3791 return false;
3792 }
3793 }
3794 add_filter( 'auto_update_plugin', 'learnpress_disable_auto_update', 10, 2 );*/
3795
3796 add_action(
3797 'in_plugin_update_message-learnpress/learnpress.php',
3798 function ( $plugin_data ) {
3799 version_update_warning( LEARNPRESS_VERSION, $plugin_data['new_version'] );
3800 }
3801 );
3802 /**
3803 * Custom message warning have new version
3804 *
3805 * @param $current_version
3806 * @param $new_version
3807 * @author hungkv
3808 */
3809 function version_update_warning( $current_version, $new_version ) {
3810 $current_version_minor_part = explode( '.', $current_version )[1];
3811 $new_version_minor_part = explode( '.', $new_version )[1];
3812 if ( $current_version_minor_part === $new_version_minor_part ) {
3813 return;
3814 }
3815
3816 $info = get_plugin_data( LP_PLUGIN_FILE );
3817 ?>
3818 <hr class="lp-update--warning__separator"/>
3819 <div class="lp-update--warning">
3820 <div>
3821 <div class="lp-update-warning__title">
3822 <?php echo esc_html__( 'Heads up, Please backup before upgrade!', 'learnpress' ); ?>
3823 </div>
3824 <div class="lp-update-warning__message">
3825 <?php echo esc_html__( 'The latest update includes some substantial changes across different areas of the plugin. We highly recommend you backup your site before upgrading, and make sure you first update in a staging environment', 'learnpress' ); ?>
3826 <?php echo esc_html__( 'Learners require WordPress version ' . $info['Requires at least'] . ' or higher.', 'learnpress' ); ?>
3827 </div>
3828 </div>
3829 </div>
3830
3831 <?php
3832 }
3833
3834 // If profile content don't have shortcode profile.
3835 function lp_add_shortcode_profile() {
3836 global $post;
3837
3838 if ( learn_press_is_profile() && is_object( $post ) ) {
3839 if ( ! has_shortcode( $post->post_content, 'learn_press_profile' ) ) {
3840 $post->post_content .= '<!-- wp:shortcode -->[' . apply_filters( 'learn-press/shortcode/profile/tag', 'learn_press_profile' ) . ']<!-- /wp:shortcode -->';
3841 }
3842
3843 wp_update_post( $post );
3844 }
3845 }
3846
3847 add_action( 'template_redirect', 'lp_add_shortcode_profile' );
3848
3849 /**
3850 * If Elementor Pro set Theme builder type "Archive", will not show content on page "Archive course"
3851 *
3852 * @editor tungnx
3853 * @author nhamdv
3854 *
3855 * @since 4.0.6
3856 * @version 1.0.1
3857 */
3858 add_filter(
3859 'elementor/theme/get_location_templates/template_id',
3860 function( $theme_template_id ) {
3861 $elementor_template_type = get_post_meta( $theme_template_id, '_elementor_template_type', true );
3862
3863 if ( in_array( $elementor_template_type, array( 'archive' ) ) ) {
3864 if ( LP_PAGE_COURSES === LP_Page_Controller::page_current() && class_exists( 'ElementorPro\Modules\ThemeBuilder\Conditions\Archive' ) ) {
3865 return false;
3866 }
3867 }
3868
3869 return $theme_template_id;
3870 }
3871 );
3872