PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / inc / lp-core-functions.php

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

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