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

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

3,731 lines 93.2 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 /**
1737 * @var WP_Query $wp_query
1738 */
1739 global $wp_query;
1740
1741 if ( $wp_query->get_queried_object() ) {
1742 return is_singular( array( LP_COURSE_CPT ) );
1743 } else {
1744 return false;
1745 }
1746 }
1747 }
1748
1749 if ( ! function_exists( 'learn_press_is_lesson' ) ) {
1750 function learn_press_is_lesson() {
1751 return is_singular( array( LP_LESSON_CPT ) );
1752 }
1753 }
1754
1755 if ( ! function_exists( 'learn_press_is_quiz' ) ) {
1756 function learn_press_is_quiz() {
1757 return is_singular( array( LP_QUIZ_CPT ) );
1758 }
1759 }
1760
1761 function lp_content_has_shortcode( $tag = '' ) {
1762 global $post;
1763
1764 return is_singular() && is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, $tag );
1765 }
1766
1767 /**
1768 * Returns true when viewing profile page.
1769 *
1770 * @return bool
1771 */
1772 function learn_press_is_profile() {
1773 $page_id = learn_press_get_page_id( 'profile' );
1774
1775 if ( $page_id && is_page( $page_id ) || lp_content_has_shortcode( 'learn_press_profile' ) ) {
1776 return true;
1777 }
1778
1779 return apply_filters( 'learn-press/is-profile', false );
1780 }
1781
1782 /**
1783 * Return true if user is in checking out page
1784 *
1785 * @return bool
1786 */
1787 function learn_press_is_checkout() {
1788 $page_id = learn_press_get_page_id( 'checkout' );
1789
1790 if ( $page_id && is_page( $page_id ) ) {
1791 return true;
1792 }
1793
1794 return apply_filters( 'learn-press/is-checkout', false );
1795 }
1796
1797 /**
1798 * Return register permalink
1799 *
1800 * @return mixed
1801 */
1802 function learn_press_get_register_url() {
1803 return apply_filters( 'learn_press_register_url', wp_registration_url() );
1804 }
1805
1806 /**
1807 * Add a new notice into queue
1808 *
1809 * @param string
1810 * @param string
1811 *
1812 * @return mixed
1813 */
1814 function learn_press_add_notice( $message, $type = 'updated' ) {
1815 LP_Admin_Notice::instance()->add( $message, $type );
1816 }
1817
1818 /**
1819 * Set user's cookie
1820 *
1821 * @param $name
1822 * @param $value
1823 * @param int $expire
1824 * @param bool $secure
1825 *
1826 * @editor tungnx
1827 * @version 1.0.2
1828 */
1829 function learn_press_setcookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) {
1830 $secure = ( 'https' === parse_url( wp_login_url(), PHP_URL_SCHEME ) );
1831
1832 @setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, $httponly );
1833 }
1834
1835 /**
1836 * Clear cookie
1837 *
1838 * @param $name
1839 */
1840 function learn_press_remove_cookie( $name ) {
1841 setcookie( $name, '', time() - YEAR_IN_SECONDS, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN );
1842
1843 if ( array_key_exists( $name, $_COOKIE ) ) {
1844 unset( $_COOKIE[ $name ] );
1845 }
1846 }
1847
1848 /**
1849 * Filter the login url so third-party can be customize
1850 *
1851 * @param string $redirect
1852 *
1853 * @return mixed
1854 */
1855 function learn_press_get_login_url( $redirect = null ) {
1856 $url = wp_login_url( $redirect );
1857 $profile_page = learn_press_get_page_link( 'profile' );
1858
1859 if ( 'yes' === LP_Settings::instance()->get( 'enable_login_profile' ) && $profile_page ) {
1860 $parse_url = parse_url( $url );
1861 $url = $profile_page . ( ! empty( $parse_url['query'] ) ? '?' . $parse_url['query'] : '' );
1862 }
1863
1864 return apply_filters( 'learn-press/login-url', $url );
1865 }
1866
1867 /**
1868 * Add variable to an url by checking the permalink structure.
1869 *
1870 * @param string $name
1871 * @param string $value
1872 * @param string $url
1873 *
1874 * @return string
1875 */
1876 function learn_press_get_endpoint_url( $name, $value, $url ) {
1877 if ( ! $url ) {
1878 $url = get_permalink();
1879 }
1880
1881 // Map endpoint to options
1882 $name = isset( LP()->query_vars[ $name ] ) ? LP()->query_vars[ $name ] : $name;
1883
1884 if ( get_option( 'permalink_structure' ) ) {
1885 if ( strstr( $url, '?' ) ) {
1886 $query_string = '?' . parse_url( $url, PHP_URL_QUERY );
1887 $url = current( explode( '?', $url ) );
1888 } else {
1889 $query_string = '';
1890 }
1891 $url = trailingslashit( $url ) . ( $name ? $name . '/' : '' ) . $value . $query_string;
1892
1893 } else {
1894 $url = esc_url_raw( add_query_arg( $name, $value, $url ) );
1895 }
1896
1897 return apply_filters( 'learn_press_get_endpoint_url', esc_url_raw( $url ), $name, $value, $url );
1898 }
1899
1900 /**
1901 * Add all endpoints from settings to the pages.
1902 */
1903 function learn_press_add_endpoints() {
1904 $settings = LP_Settings::instance();
1905
1906 $endpoints = $settings->get_checkout_endpoints();
1907 if ( $endpoints ) {
1908 foreach ( $endpoints as $endpoint => $value ) {
1909 LP()->query_vars[ $endpoint ] = $value;
1910 add_rewrite_endpoint( $value, EP_PAGES );
1911 }
1912 }
1913
1914 $endpoints = $settings->get_profile_endpoints();
1915 if ( $endpoints ) {
1916 foreach ( $endpoints as $endpoint => $value ) {
1917 LP()->query_vars[ $endpoint ] = $value;
1918 add_rewrite_endpoint( $value, EP_PAGES );
1919 }
1920 }
1921
1922 $endpoints = $settings->get( 'quiz_endpoints' );
1923 if ( $endpoints ) {
1924 foreach ( $endpoints as $endpoint => $value ) {
1925 $endpoint = preg_replace( '!_!', '-', $endpoint );
1926 LP()->query_vars[ $endpoint ] = $value;
1927 add_rewrite_endpoint(
1928 $value, /*EP_ROOT | */
1929 EP_PAGES
1930 );
1931 }
1932 }
1933 }
1934
1935 add_action( 'init', 'learn_press_add_endpoints' );
1936
1937 function learn_press_is_yes( $value ) {
1938 return ( $value === 1 ) || ( $value === '1' ) || ( $value == 'yes' ) || ( $value == true ) || ( $value == 'on' );
1939 }
1940
1941 /**
1942 * @param mixed $value
1943 *
1944 * @return bool
1945 */
1946 function _is_false_value( $value ) {
1947 if ( is_numeric( $value ) ) {
1948 return $value == 0;
1949 } elseif ( is_string( $value ) ) {
1950 return ( empty( $value ) || is_null( $value ) || in_array( $value, array( 'no', 'off', 'false' ) ) );
1951 }
1952
1953 return ! ! $value;
1954 }
1955
1956 /**
1957 * Map the query vars from LP to query vars of WP core
1958 * when WP parse the requesting.
1959 */
1960 function learn_press_parse_request() {
1961 global $wp;
1962
1963 // Map query vars to their keys, or get them if endpoints are not supported
1964 foreach ( LP()->query_vars as $key => $var ) {
1965 if ( isset( $_GET[ $var ] ) ) {
1966 $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $_GET[ $var ] ?? '' );
1967 } elseif ( isset( $wp->query_vars[ $var ] ) ) {
1968 $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $wp->query_vars[ $var ] ?? '' );
1969 }
1970 }
1971 }
1972
1973 add_action( 'parse_request', 'learn_press_parse_request' );
1974
1975 if ( ! function_exists( 'learn_press_reset_auto_increment' ) ) {
1976 /**
1977 * Reset AUTO INCREMENT of the table.
1978 *
1979 * @param $table
1980 */
1981 function learn_press_reset_auto_increment( $table ) {
1982 global $wpdb;
1983 $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}$table AUTO_INCREMENT = %d", 1 ) );
1984 }
1985 }
1986
1987 /**
1988 * @param string $handle
1989 * @param bool $hash
1990 *
1991 * @return string
1992 */
1993 function learn_press_get_log_file_path( $handle, $hash = false ) {
1994 if ( $hash ) {
1995 $hash = '-' . sanitize_file_name( wp_hash( $handle ) );
1996 }
1997
1998 return trailingslashit( LP_LOG_PATH ) . $handle . $hash . '.log';
1999 }
2000
2001 /**
2002 * Get the cart object in checkout page
2003 *
2004 * @return LP_Cart
2005 */
2006 function learn_press_get_checkout_cart() {
2007 return apply_filters( 'learn_press_checkout_cart', LP()->cart );
2008 }
2009
2010 /*function learn_press_front_scripts() {
2011 if ( is_admin() ) {
2012 return;
2013 }
2014 $js = array(
2015 'ajax' => admin_url( 'admin-ajax.php' ),
2016 'plugin_url' => LP()->plugin_url(),
2017 'siteurl' => home_url(),
2018 'current_url' => learn_press_get_current_url(),
2019 'localize' => array(
2020 'button_ok' => __( 'OK', 'learnpress' ),
2021 'button_cancel' => __( 'Cancel', 'learnpress' ),
2022 'button_yes' => __( 'Yes', 'learnpress' ),
2023 'button_no' => __( 'No', 'learnpress' ),
2024 ),
2025 );
2026 foreach ( $js as $k => $v ) {
2027 LP_Assets::add_param( $k, $v, array( 'learn-press-single-course', 'learn-press-global' ), 'LP_Settings' );
2028 }
2029 }
2030
2031 add_action( 'wp_print_scripts', 'learn_press_front_scripts' );*/
2032
2033 function learn_press_user_time( $time, $format = 'timestamp' ) {
2034 if ( is_string( $time ) ) {
2035 $time = @strtotime( $time );
2036 }
2037 $time = $time + ( get_option( 'gmt_offset' ) - $_COOKIE['timezone'] / 60 ) * HOUR_IN_SECONDS;
2038 switch ( $format ) {
2039 case 'timestamp':
2040 return $time;
2041 default:
2042 return date( 'Y-m-d H:i:s', $time );
2043 }
2044 }
2045
2046 function learn_press_get_current_version() {
2047 $data = get_plugin_data( LP_PLUGIN_FILE, $markup = true, $translate = true );
2048
2049 return $data['Version'];
2050 }
2051
2052 /**
2053 * Get current tab is displaying in user profile.
2054 * If there is no tab then get the first tab in
2055 * the list of tabs.
2056 *
2057 * @param bool $default
2058 *
2059 * @return mixed|string
2060 */
2061 function learn_press_get_current_profile_tab( $default = true ) {
2062 global $wp_query, $wp;
2063 $current = '';
2064
2065 if ( ! empty( $_REQUEST['tab'] ) ) {
2066 $current = LP_Helper::sanitize_params_submitted( $_REQUEST['tab'] );
2067 } elseif ( ! empty( $wp_query->query_vars['tab'] ) ) {
2068 $current = $wp_query->query_vars['tab'];
2069 } elseif ( ! empty( $wp->query_vars['view'] ) ) {
2070 $current = $wp->query_vars['view'];
2071 } else {
2072 $tabs = learn_press_get_user_profile_tabs();
2073 if ( $default && $tabs ) {
2074 // Fixed for array_keys does not work with ArrayAccess instance
2075 if ( $tabs instanceof LP_Profile_Tabs ) {
2076 $tabs = $tabs->tabs();
2077 }
2078
2079 $tab_keys = array_keys( $tabs );
2080 $current = reset( $tab_keys );
2081 }
2082 }
2083
2084 return $current;
2085 }
2086
2087 add_action( 'init', 'learn_press_get_current_profile_tab' );
2088
2089 function learn_press_profile_tab_exists( $tab ) {
2090 $tabs = learn_press_get_user_profile_tabs();
2091
2092 if ( $tabs ) {
2093 return ! empty( $tabs[ $tab ] ) ? true : false;
2094 }
2095
2096 return false;
2097 }
2098
2099 /**
2100 * Replace the spacing with the + (plus) char.
2101 *
2102 * @param string $string
2103 *
2104 * @return string
2105 */
2106 function _learn_press_urlencode( $string ) {
2107 return preg_replace( '/\s/', '+', $string );
2108 }
2109
2110 /**
2111 * Point the archive post type link to course page if current
2112 * post type is course and the page for displaying course is
2113 * setup.
2114 *
2115 * @param string $link
2116 * @param string $post_type
2117 *
2118 * @return string
2119 */
2120 function learn_press_post_type_archive_link( $link, $post_type ) {
2121 if ( $post_type == LP_COURSE_CPT && learn_press_get_page_id( 'courses' ) ) {
2122 $link = learn_press_get_page_link( 'courses' );
2123 }
2124
2125 return $link;
2126 }
2127
2128 add_filter( 'post_type_archive_link', 'learn_press_post_type_archive_link', 10, 2 );
2129
2130 function learn_press_single_term_title( $prefix = '', $display = true ) {
2131 $term = get_queried_object();
2132
2133 if ( ! $term ) {
2134 return '';
2135 }
2136
2137 if ( learn_press_is_course_category() ) {
2138 $term_name = apply_filters( 'single_course_category_title', $term->name );
2139 } elseif ( learn_press_is_course_tag() ) {
2140 $term_name = apply_filters( 'single_course_tag_title', $term->name );
2141 } elseif ( learn_press_is_course_taxonomy() ) {
2142 $term_name = apply_filters( 'single_course_term_title', $term->name );
2143 } else {
2144 return single_term_title( $prefix, $display );
2145 }
2146
2147 if ( empty( $term_name ) ) {
2148 return single_term_title( $prefix, $display );
2149 }
2150
2151 if ( $display ) {
2152 echo wp_kses_post( $prefix . $term_name );
2153 }
2154
2155 return $prefix . $term_name;
2156 }
2157
2158 /**
2159 * Control the template file if user is searching course.
2160 * Use the template of archive course to display the
2161 * result if there is a flag in request to search course.
2162 *
2163 * @param string $template
2164 *
2165 * @return string
2166 */
2167 function learn_press_search_template( $template ) {
2168 if ( ! empty( $_REQUEST['ref'] ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course' ) {
2169 $template = learn_press_locate_template( 'archive-course.php' );
2170 }
2171
2172 return $template;
2173 }
2174
2175 /**
2176 * Auto enroll user to a course after an order is completed
2177 * if the option auto-enroll is turn on.
2178 *
2179 * @param int $order_id
2180 *
2181 * @return mixed
2182 * @editor tungnx
2183 */
2184 function learn_press_auto_enroll_user_to_courses( $order_id ) {
2185 _deprecated_function( __FUNCTION__, '4.1.3' );
2186 }
2187
2188 // add_action( 'learn_press_order_status_completed', 'learn_press_auto_enroll_user_to_courses' );
2189
2190 /**
2191 * Return true if enable cart
2192 *
2193 * @return bool
2194 */
2195 function learn_press_is_enable_cart() {
2196 return defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART == true;
2197 }
2198
2199 /**
2200 * Short way to get checkout object
2201 *
2202 * @param array
2203 *
2204 * @return LP_Checkout
2205 */
2206 function learn_press_get_checkout( $args = null ) {
2207 $checkout = LP_Checkout::instance();
2208
2209 if ( is_array( $args ) ) {
2210 foreach ( $args as $k => $v ) {
2211 $checkout->{$k} = $v;
2212 }
2213 }
2214
2215 return $checkout;
2216 }
2217
2218 if ( defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART ) {
2219 add_filter( 'learn_press_checkout_settings', '_learn_press_cart_settings', 10, 2 );
2220 function _learn_press_cart_settings( $settings, $class ) {
2221 $settings = array_merge(
2222 $settings,
2223 array(
2224 array(
2225 'title' => __( 'Cart', 'learnpress' ),
2226 'type' => 'title',
2227 ),
2228 array(
2229 'title' => __( 'Enable cart', 'learnpress' ),
2230 'desc' => __(
2231 'Check this option to enable user purchase multiple courses at one time.',
2232 'learnpress'
2233 ),
2234 'id' => $class->get_field_name( 'enable_cart' ),
2235 'default' => 'yes',
2236 'type' => 'checkbox',
2237 ),
2238 array(
2239 'title' => __( 'Add to cart redirect', 'learnpress' ),
2240 'desc' => __( 'Redirect to checkout immediately after adding course to cart.', 'learnpress' ),
2241 'id' => $class->get_field_name( 'redirect_after_add' ),
2242 'default' => 'yes',
2243 'type' => 'checkbox',
2244 ),
2245 array(
2246 'title' => __( 'AJAX add to cart', 'learnpress' ),
2247 'desc' => __( 'Using AJAX to add course to cart.', 'learnpress' ),
2248 'id' => $class->get_field_name( 'ajax_add_to_cart' ),
2249 'default' => 'no',
2250 'type' => 'checkbox',
2251 ),
2252 array(
2253 'title' => __( 'Cart page', 'learnpress' ),
2254 'id' => $class->get_field_name( 'cart_page_id' ),
2255 'default' => '',
2256 'type' => 'pages-dropdown',
2257 ),
2258 )
2259 );
2260
2261 return $settings;
2262 }
2263 } else {
2264 add_filter( 'learn_press_enable_cart', '_learn_press_enable_cart', 1000 );
2265 function _learn_press_enable_cart( $r ) {
2266 return false;
2267 }
2268
2269 add_filter( 'learn_press_get_template', '_learn_press_enroll_button', 1000, 5 );
2270 function _learn_press_enroll_button( $located, $template_name, $args, $template_path, $default_path ) {
2271 if ( $template_name == 'single-course/enroll-button.php' ) {
2272 $located = learn_press_locate_template(
2273 'single-course/enroll-button-new.php',
2274 $template_path,
2275 $default_path
2276 );
2277 }
2278
2279 return $located;
2280 }
2281 }
2282
2283 /**
2284 * Returns checkout url from setting
2285 *
2286 * @return string
2287 */
2288 function learn_press_get_checkout_url() {
2289 $checkout_url = learn_press_get_page_link( 'checkout' );
2290
2291 return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
2292 }
2293
2294 /**
2295 * @return string
2296 */
2297 function learn_press_checkout_needs_payment() {
2298 return LP()->cart->needs_payment();
2299 }
2300
2301 /**
2302 * Return plugin basename
2303 *
2304 * @param string $filepath
2305 *
2306 * @return string
2307 */
2308 /*
2309 function learn_press_plugin_basename( $filepath ) {
2310 $file = str_replace( '\\', '/', $filepath );
2311 $file = preg_replace( '|/+|', '/', $file );
2312 $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR );
2313 $plugin_dir = preg_replace( '|/+|', '/', $plugin_dir );
2314 $mu_plugin_dir = str_replace( '\\', '/', WPMU_PLUGIN_DIR );
2315 $mu_plugin_dir = preg_replace( '|/+|', '/', $mu_plugin_dir );
2316 $sp_plugin_dir = dirname( $filepath );
2317 $sp_plugin_dir = dirname( $sp_plugin_dir );
2318 $sp_plugin_dir = str_replace( '\\', '/', $sp_plugin_dir );
2319 $sp_plugin_dir = preg_replace( '|/+|', '/', $sp_plugin_dir );
2320
2321 $file = preg_replace(
2322 '#^' . preg_quote( $sp_plugin_dir, '#' ) . '/|^' . preg_quote(
2323 $plugin_dir,
2324 '#'
2325 ) . '/|^' . preg_quote(
2326 $mu_plugin_dir,
2327 '#'
2328 ) . '/#',
2329 '',
2330 $file
2331 );
2332 $file = trim( $file, '/' );
2333
2334 return strtolower( $file );
2335 }*/
2336
2337 /**
2338 * Update log data for each LP version into wp option.
2339 *
2340 * @param string $version
2341 * @param mixed $data
2342 */
2343 function learn_press_update_log( $version, $data ) {
2344 $logs = get_option( 'learn_press_update_logs' );
2345 if ( ! $logs ) {
2346 $logs = array( $version => $data );
2347 } else {
2348 $logs[ $version ] = $data;
2349 }
2350 update_option( 'learn_press_update_logs', $logs );
2351 }
2352
2353 /**
2354 * Output variables to screen for debugging.
2355 */
2356 function learn_press_debug() {
2357 $args = func_get_args();
2358 $debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
2359
2360 echo '<pre>';
2361 print_r( $debug );
2362 $arg = false;
2363
2364 if ( $args ) {
2365 foreach ( $args as $arg ) {
2366 echo "\n======LearnPress Debug=======\n";
2367 print_r( $arg );
2368 echo "\n=============================\n";
2369 }
2370 }
2371 echo '</pre>';
2372
2373 if ( true === $arg ) {
2374 die( __FUNCTION__ );
2375 }
2376 }
2377
2378 /**
2379 * Get current time to user for calculate remaining time of quiz.
2380 *
2381 * @return int
2382 */
2383 function learn_press_get_current_time() {
2384 $current_time = apply_filters( 'learn_press_get_current_time', 0 );
2385
2386 if ( $current_time > 0 ) {
2387 return $current_time;
2388 }
2389
2390 $a = current_time( 'timestamp' );
2391 $b = time();
2392 $c = current_time( 'mysql' );
2393 $d = strtotime( $c );
2394
2395 if ( $d == $a ) {
2396 return $a;
2397 } else {
2398 return $b;
2399 }
2400 }
2401
2402 function learn_press_get_requested_post_type() {
2403 global $pagenow;
2404 if ( $pagenow == 'post-new.php' && ! empty( $_REQUEST['post_type'] ) ) {
2405 $post_type = LP_Helper::sanitize_params_submitted( $_REQUEST['post_type'] );
2406 } else {
2407 $post_id = learn_press_get_post();
2408 $post_type = learn_press_get_post_type( $post_id );
2409 }
2410
2411 return $post_type;
2412 }
2413
2414 /**
2415 * Get human string from grade slug.
2416 *
2417 * @param string $slug
2418 *
2419 * @return string
2420 */
2421 function learn_press_get_graduation_text( $slug ) {
2422 switch ( $slug ) {
2423 case 'passed':
2424 $text = esc_html__( 'Passed', 'learnpress' );
2425 break;
2426 case 'failed':
2427 $text = esc_html__( 'Failed', 'learnpress' );
2428 break;
2429 case 'in-progress':
2430 $text = esc_html__( 'In Progress', 'learnpress' );
2431 break;
2432 default:
2433 $text = $slug;
2434 }
2435
2436 return apply_filters( 'learn-press/get-graduation-text', $text, $slug );
2437 }
2438
2439 /*function learn_press_execute_time( $n = 1 ) {
2440 static $time;
2441 if ( empty( $time ) ) {
2442 $time = microtime( true );
2443
2444 return $time;
2445 } else {
2446 $execute_time = microtime( true ) - $time;
2447
2448 echo 'Execute time ' . $n * $execute_time . "\n";
2449 $time = 0;
2450
2451 return $execute_time;
2452 }
2453 }*/
2454
2455 if ( ! function_exists( 'learn_press_is_negative_value' ) ) {
2456 function learn_press_is_negative_value( $value ) {
2457 $return = in_array( $value, array( 'no', 'off', 'false', '0' ) ) || ! $value || $value == '' || $value == null;
2458
2459 return $return;
2460 }
2461 }
2462
2463 /**
2464 * Filter to comment reply link to fix bug the link is invalid for
2465 * lesson or quiz.
2466 *
2467 * @param string $link
2468 * @param array $args
2469 * @param WP_Comment $comment
2470 * @param WP_Post $post
2471 *
2472 * @return string
2473 */
2474 function learn_press_comment_reply_link( $link, $args = array(), $comment = null, $post = null ) {
2475
2476 $post_type = learn_press_get_post_type( $post );
2477
2478 if ( ! learn_press_is_support_course_item_type( $post_type ) ) {
2479 return $link;
2480 }
2481
2482 $course_item = LP_Global::course_item();
2483
2484 if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
2485 $link = sprintf(
2486 '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
2487 esc_url_raw( wp_login_url( get_permalink() ) ),
2488 $args['login_text']
2489 );
2490 } elseif ( $course_item ) {
2491 $onclick = sprintf(
2492 'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
2493 $args['add_below'],
2494 $comment->comment_ID,
2495 $args['respond_id'],
2496 $post->ID
2497 );
2498
2499 $link = sprintf(
2500 "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
2501 esc_url_raw(
2502 add_query_arg(
2503 array(
2504 'replytocom' => $comment->comment_ID,
2505 ),
2506 $course_item->get_permalink()
2507 )
2508 ) . '#' . $args['respond_id'],
2509 $onclick,
2510 esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
2511 $args['reply_text']
2512 );
2513 }
2514
2515 return $link;
2516 }
2517
2518 add_filter( 'comment_reply_link', 'learn_press_comment_reply_link', 10, 4 );
2519
2520 function learn_press_deprecated_function( $function, $version, $replacement = null ) {
2521 if ( LP_Debug::is_debug() ) {
2522 _deprecated_function( $function, $version, $replacement );
2523 }
2524 }
2525
2526
2527 /**
2528 * Sanitize content of tooltip
2529 *
2530 * @param string $tooltip
2531 * @param bool $html
2532 *
2533 * @return string
2534 */
2535 function learn_press_sanitize_tooltip( $tooltip, $html = false ) {
2536 if ( $html ) {
2537 $tooltip = htmlspecialchars(
2538 wp_kses(
2539 html_entity_decode( $tooltip ),
2540 array(
2541 'br' => array(),
2542 'em' => array(),
2543 'strong' => array(),
2544 'small' => array(),
2545 'span' => array(),
2546 'ul' => array(),
2547 'li' => array(),
2548 'ol' => array(),
2549 'p' => array(),
2550 )
2551 )
2552 );
2553 } else {
2554 $tooltip = esc_attr( $tooltip );
2555 }
2556
2557 return $tooltip;
2558 }
2559
2560 function learn_press_tooltip( $tooltip, $html = false ) {
2561 $tooltip = learn_press_sanitize_tooltip( $tooltip, $html );
2562 echo '<span class="learn-press-tooltip" data-tooltip="' . esc_attr( $tooltip ) . '"></span>';
2563 }
2564
2565 /**
2566 * Get timezone offset from wp settings.
2567 *
2568 * @return float|int
2569 * @since 3.0.0
2570 */
2571 function learn_press_timezone_offset() {
2572 if ( $tz = get_option( 'timezone_string' ) ) {
2573 $timezone = new DateTimeZone( $tz );
2574
2575 return $timezone->getOffset( new DateTime( 'now' ) );
2576 } else {
2577 return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS;
2578 }
2579 }
2580
2581 /**
2582 * Get default static pages of LP.
2583 *
2584 * @return array
2585 *
2586 * @since 3.0.0
2587 */
2588 function learn_press_static_page_ids() {
2589 $pages = LP_Object_Cache::get( 'static-page-ids', 'learn-press' );
2590
2591 if ( false === $pages ) {
2592 $pages = array(
2593 'checkout' => learn_press_get_page_id( 'checkout' ),
2594 'courses' => learn_press_get_page_id( 'courses' ),
2595 'profile' => learn_press_get_page_id( 'profile' ),
2596 'become_a_teacher' => learn_press_get_page_id( 'become_a_teacher' ),
2597 );
2598
2599 foreach ( $pages as $name => $id ) {
2600 if ( ! get_post( $id ) ) {
2601 $pages[ $name ] = 0;
2602 }
2603 }
2604
2605 LP_Object_Cache::set( 'static-page-ids', $pages, 'learn-press' );
2606 }
2607
2608 return apply_filters( 'learn-press/static-page-ids', $pages );
2609 }
2610
2611 /**
2612 * Get default static pages of LP.
2613 *
2614 * @param bool $name - Optional. TRUE will return name only.
2615 *
2616 * @return array
2617 *
2618 * @since 3.0.0
2619 */
2620 function learn_press_static_pages( $name = false ) {
2621 $pages = apply_filters(
2622 'learn-press/static-pages',
2623 array(
2624 'checkout' => _x( 'Checkout', 'static-page-name', 'learnpress' ),
2625 'courses' => _x( 'Courses', 'static-page-name', 'learnpress' ),
2626 'profile' => _x( 'Profile', 'static-page-name', 'learnpress' ),
2627 'become_a_teacher' => _x( 'Become a Teacher', 'static-page-name', 'learnpress' ),
2628 )
2629 );
2630
2631 if ( $name ) {
2632 return array_keys( $pages );
2633 }
2634
2635 return $pages;
2636 }
2637
2638 /*function learn_press_cache_path( $group, $key = '' ) {
2639 $path = LP_PLUGIN_PATH . 'cache';
2640 if ( ! file_exists( $path ) ) {
2641 @mkdir( $path );
2642 }
2643 $path = $path . '/' . $group;
2644
2645 if ( ! file_exists( $path ) ) {
2646 @mkdir( $path );
2647 }
2648 if ( $key ) {
2649 $path = $path . '/' . $key . '.ch';
2650 }
2651
2652 return $path;
2653 }*/
2654
2655 function learn_press_cache_get( $key, $group, $found = null ) {
2656 //$file = learn_press_cache_path( $group, $key );
2657 $data = wp_cache_get( $key, $group, $found );
2658
2659 /*if ( ! file_exists( $file ) ) {
2660 return false;
2661 }*/
2662
2663 /*if ( false === $data ) {
2664 $content = file_get_contents( $file );
2665
2666 if ( file_exists( $file ) && $content ) {
2667 try {
2668 $data = unserialize( $content );
2669 } catch ( Exception $ex ) {
2670 print_r( $content );
2671 die();
2672 }
2673 wp_cache_set( $key, $data, $group, $found );
2674 }
2675 }*/
2676
2677 return $data;
2678 }
2679
2680 function learn_press_cache_set( $key, $data, $group = '', $expire = 0 ) {
2681 //$file = learn_press_cache_path( $group, $key );
2682 wp_cache_set( $key, $data, $group, $expire );
2683
2684 /*if ( ! is_string( $data ) ) {
2685 $data = serialize( $data );
2686 }
2687 file_put_contents( $file, $data );*/
2688 }
2689
2690 function learn_press_cache_replace( $key, $data, $group = '', $expire = 0 ) {
2691 wp_cache_replace( $key, $data, $group, $expire );
2692 }
2693
2694 function learn_press_cache_add( $key, $data, $group = '', $expire = 0 ) {
2695 wp_cache_add( $key, $data, $group, $expire );
2696 }
2697
2698 if ( ! function_exists( 'learn_press_get_widget_course_object' ) ) {
2699 /**
2700 * Get course object for widget query.
2701 *
2702 * @param $query
2703 *
2704 * @return array
2705 * @deprecated v4.1.6.1 - we will remove on the version 4.1.7
2706 */
2707 function learn_press_get_widget_course_object( $query ) {
2708
2709 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2710
2711 global $wpdb;
2712
2713 $posts = $wpdb->get_results( $query );
2714 if ( $posts ) {
2715 // get lp courses object from WordPress post
2716 $courses = array_map( 'learn_press_get_lp_course', $posts );
2717 $courses = array_filter( $courses );
2718
2719 } else {
2720 $courses = array();
2721 }
2722
2723 return $courses;
2724 }
2725 }
2726
2727 if ( ! function_exists( 'learn_press_get_lp_course' ) ) {
2728 /**
2729 * Get learn press course from WordPress post object
2730 *
2731 * @param object - reference $post WordPress post object
2732 *
2733 * @return LP_Course course
2734 * @deprecated v4.1.6.1 - we will remove on the version 4.1.7
2735 */
2736 function learn_press_get_lp_course( $post ) {
2737 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2738
2739 $id = $post->ID;
2740 $course = null;
2741 if ( ! empty( $id ) ) {
2742 // $course = new LP_Course( $id );
2743 $course = learn_press_get_course( $id );
2744 }
2745
2746 return $course;
2747 }
2748 }
2749
2750 /**
2751 * Get all items are unassigned to any course.
2752 *
2753 * @param string|array $type - Optional. Types of items to get, default is all.
2754 *
2755 * @return array
2756 * @since 3.0.0
2757 * @deprecated 4.1.4.1 - Will remove on version 4.1.7
2758 */
2759 function learn_press_get_unassigned_items( $type = '' ) {
2760 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2761
2762 global $wpdb;
2763
2764 if ( ! $type ) {
2765 $type = learn_press_course_get_support_item_types();
2766 $type = array_keys( $type );
2767 }
2768
2769 settype( $type, 'array' );
2770 $key = 'items-' . md5( serialize( $type ) );
2771
2772 if ( false === ( $items = LP_Object_Cache::get( $key, 'learn-press/unassigned' ) ) ) {
2773 $format = array_fill( 0, sizeof( $type ), '%s' );
2774
2775 $query = $wpdb->prepare(
2776 "
2777 SELECT p.ID
2778 FROM {$wpdb->posts} p
2779 WHERE p.post_type IN(" . join( ',', $format ) . ")
2780 AND p.ID NOT IN(
2781 SELECT si.item_id
2782 FROM {$wpdb->learnpress_section_items} si
2783 INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
2784 WHERE p.post_type IN(" . join( ',', $format ) . ')
2785 )
2786 AND p.post_status NOT IN(%s, %s)
2787 ',
2788 array_merge( $type, $type, array( 'auto-draft', 'trash' ) )
2789 );
2790
2791 $items = $wpdb->get_col( $query );
2792
2793 //LP_Debug::var_dump($query, __FILE__, __LINE__);
2794
2795 LP_Object_Cache::set( $key, $items, 'learn-press/unassigned' );
2796 }
2797
2798 return $items;
2799 }
2800
2801 /**
2802 * Get all questions are unassigned to any quiz.
2803 *
2804 * @return array
2805 * @since 3.0.0
2806 * @deprecated 4.1.6.1 - Will remove on version 4.1.7
2807 */
2808 function learn_press_get_unassigned_questions() {
2809 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2810
2811 global $wpdb;
2812
2813 if ( false === ( $questions = LP_Object_Cache::get( 'questions', 'learn-press/unassigned' ) ) ) {
2814 $query = $wpdb->prepare(
2815 "
2816 SELECT p.ID
2817 FROM {$wpdb->posts} p
2818 WHERE p.post_type = %s
2819 AND p.ID NOT IN(
2820 SELECT qq.question_id
2821 FROM {$wpdb->learnpress_quiz_questions} qq
2822 INNER JOIN {$wpdb->posts} p ON p.ID = qq.question_id
2823 WHERE p.post_type = %s
2824 )
2825 AND p.post_status NOT IN(%s, %s)
2826 ",
2827 LP_QUESTION_CPT,
2828 LP_QUESTION_CPT,
2829 'auto-draft',
2830 'trash'
2831 );
2832
2833 $questions = $wpdb->get_col( $query );
2834 LP_Object_Cache::set( 'questions', $questions, 'learn-press/unassigned' );
2835 }
2836
2837 return $questions;
2838 }
2839
2840 /**
2841 * Callback function for sorting to array|object by key|prop priority.
2842 *
2843 * @param array|object $a
2844 * @param array|object $b
2845 *
2846 * @return int
2847 * @since 3.0.0
2848 */
2849 function learn_press_sort_list_by_priority_callback( $a, $b ) {
2850 $a_priority = null;
2851 $b_priority = null;
2852
2853 if ( is_array( $a ) && array_key_exists( 'priority', $a ) ) {
2854 $a_priority = $a['priority'];
2855 } elseif ( is_object( $a ) ) {
2856 if ( is_callable( array( $a, 'get_priority' ) ) ) {
2857 $a_priority = $a->get_priority();
2858 } elseif ( property_exists( $a, 'priority' ) ) {
2859 $a_priority = $a->priority;
2860 }
2861 }
2862
2863 if ( is_array( $b ) && array_key_exists( 'priority', $b ) ) {
2864 $b_priority = $b['priority'];
2865 } elseif ( is_object( $b ) ) {
2866 if ( is_callable( array( $b, 'get_priority' ) ) ) {
2867 $b_priority = $b->get_priority();
2868 } elseif ( property_exists( $b, 'priority' ) ) {
2869 $b_priority = $b->priority;
2870 }
2871 }
2872
2873 if ( $a_priority === $b_priority ) {
2874 return 0;
2875 }
2876
2877 return ( $a_priority < $b_priority ) ? - 1 : 1;
2878 }
2879
2880 /**
2881 * Localize date with custom format.
2882 *
2883 * @param string $timestamp
2884 * @param string $format
2885 * @param bool $gmt
2886 *
2887 * @return string
2888 * @since 3.0.0
2889 */
2890 function learn_press_date_i18n( $timestamp = '', $format = '', $gmt = false ) {
2891 if ( ! $format ) {
2892 $format = get_option( 'date_format' );
2893 }
2894
2895 return date_i18n( $format, $timestamp, $gmt );
2896 }
2897
2898 function learn_press_date() {
2899
2900 }
2901
2902 /**
2903 * Remove user items.
2904 *
2905 * @param int $item_id
2906 * @param int $course_id
2907 * @param int $user_id
2908 * @param int $keep
2909 *
2910 * @since 3.0.8
2911 * @deprecated 4.1.6.1 - Will remove on version 4.1.7
2912 */
2913 function learn_press_remove_user_items_history( $item_id, $course_id, $user_id, $keep = 10 ) {
2914 _deprecated_function( __FUNCTION__, '4.1.6.1' );
2915
2916 $user = learn_press_get_user( $user_id );
2917 if ( $rows = $user->get_item_archive( $item_id, $course_id ) ) {
2918
2919 global $wpdb;
2920
2921 $args = array( $user_id, $item_id, $course_id );
2922 $query = $wpdb->prepare(
2923 "
2924 DELETE
2925 FROM {$wpdb->learnpress_user_items}
2926 WHERE user_id = %d AND item_id = %d
2927 AND ref_id = %d
2928 ",
2929 $args
2930 );
2931
2932 if ( $keep ) {
2933 $user_item_ids = array_keys( $rows );
2934 $user_item_ids = array_splice( $user_item_ids, 0, $keep );
2935 $format = array_fill( 0, sizeof( $user_item_ids ), '%d' );
2936
2937 $query .= $wpdb->prepare( ' AND user_item_id NOT IN(' . join( ',', $format ) . ')', $user_item_ids );
2938 }
2939
2940 $wpdb->query( $query );
2941 }
2942 }
2943
2944 /**
2945 * Get item types of course support for blocking. Default is lp_lesson
2946 *
2947 * @return array
2948 * @since 3.0.0
2949 */
2950 function learn_press_get_block_course_item_types() {
2951 return apply_filters( 'learn-press/block-course-item-types', array( LP_LESSON_CPT, LP_QUIZ_CPT ) );
2952 }
2953
2954 /**
2955 * Get post type of a post from cache.
2956 * If there is no data stored in cache then
2957 * get it from WP API.
2958 *
2959 * @param int|WP_Post $post
2960 *
2961 * @return string
2962 * @since 3.1.0
2963 */
2964 function learn_press_get_post_type( $post ) {
2965 $post_types = LP_Object_Cache::get( 'post-types', 'learn-press' );
2966
2967 if ( false === $post_types ) {
2968 $post_types = array();
2969 }
2970
2971 if ( is_object( $post ) ) {
2972 $post_id = $post->ID;
2973 } else {
2974 $post_id = absint( $post );
2975 }
2976
2977 if ( empty( $post_types[ $post_id ] ) ) {
2978 $post_type = get_post_type( $post_id );
2979 $post_types[ $post_id ] = $post_type;
2980 LP_Object_Cache::set( 'post-types', $post_types, 'learn-press' );
2981 } else {
2982 $post_type = $post_types[ $post_id ];
2983 }
2984
2985 return $post_type;
2986 }
2987
2988 /**
2989 * Add post type of a post into cache
2990 *
2991 * @param int|array $id
2992 * @param string $type
2993 *
2994 * @since 3.1.0
2995 */
2996 function learn_press_cache_add_post_type( $id, $type = '' ) {
2997 if ( false === ( $post_types = LP_Object_Cache::get( 'post-types', 'learn-press' ) ) ) {
2998 $post_types = array();
2999 }
3000
3001 if ( func_num_args() == 1 && is_array( $id ) ) {
3002 $post_types = $post_types + $id;
3003 } else {
3004 $post_types[ $id ] = $type;
3005 }
3006
3007 LP_Object_Cache::set( 'post-types', $post_types, 'learn-press' );
3008 }
3009
3010 function learn_press_has_option( $name ) {
3011 global $wpdb;
3012
3013 $query = $wpdb->prepare( "SELECT option_id FROM {$wpdb->options} WHERE option_name = %s", $name );
3014
3015 return $wpdb->get_var( $query ) > 0;
3016 }
3017
3018 /**
3019 * Update option to enable shuffle themes for ad.
3020 *
3021 * @since 3.2.1
3022 */
3023 function _learn_press_schedule_enable_shuffle_themes() {
3024 update_option( 'learn_press_ad_shuffle_themes', 'yes' );
3025 }
3026
3027 add_action( 'learn-press/schedule-enable-shuffle-themes', '_learn_press_schedule_enable_shuffle_themes' );
3028
3029 function learn_press_show_log() {
3030 if ( trim( LP_Request::get( 'show_log' ) ) === md5( AUTH_KEY ) ) {
3031 call_user_func_array( 'learn_press_debug', func_get_args() );
3032 }
3033 }
3034
3035 /**
3036 * @return array
3037 * @since 3.2.6
3038 */
3039 function learn_press_global_script_params() {
3040 $js = array(
3041 'ajax' => admin_url( 'admin-ajax.php' ),
3042 'plugin_url' => LP()->plugin_url(),
3043 'siteurl' => home_url(),
3044 'current_url' => learn_press_get_current_url(),
3045 'theme' => get_stylesheet(),
3046 'localize' => array(
3047 'button_ok' => __( 'OK', 'learnpress' ),
3048 'button_cancel' => __( 'Cancel', 'learnpress' ),
3049 'button_yes' => __( 'Yes', 'learnpress' ),
3050 'button_no' => __( 'No', 'learnpress' ),
3051 ),
3052 'root' => esc_url_raw( rest_url() ),
3053 'nonce' => wp_create_nonce( 'wp_rest' ),
3054 );
3055
3056 return $js;
3057 }
3058
3059 /**
3060 * Get url for setup cron job on server.
3061 *
3062 * @return string
3063 * @since 3.3.0
3064 */
3065 function learn_press_get_cron_url() {
3066 $nonce = get_option( 'learnpress_cron_url_nonce' );
3067
3068 if ( ! $nonce ) {
3069 $nonce = md5( microtime( true ) );
3070 update_option( 'learnpress_cron_url_nonce', $nonce );
3071 }
3072 $url = add_query_arg(
3073 array(
3074 'lp-ajax' => 'cron',
3075 'sid' => $nonce,
3076 ),
3077 get_home_url()
3078 );
3079
3080 return $url;
3081 }
3082
3083 /**
3084 * Get courses expired.
3085 *
3086 * @return array
3087 * @since 3.3.0
3088 */
3089 function learn_press_get_expired_courses() {
3090 global $wpdb;
3091
3092 $query = $wpdb->prepare(
3093 "
3094 SELECT X.*
3095 FROM(
3096 SELECT ui.*
3097 FROM {$wpdb->learnpress_user_items} ui
3098 LEFT JOIN {$wpdb->learnpress_user_items} uix
3099 ON ui.item_id = uix.item_id
3100 AND ui.user_id = uix.user_id
3101 AND ui.user_item_id < uix.user_item_id
3102 WHERE uix.user_item_id IS NULL
3103 ) X
3104 INNER JOIN {$wpdb->users} u ON u.ID = X.user_id
3105 INNER JOIN {$wpdb->posts} p ON p.ID = X.item_id
3106 WHERE X.item_type = %s
3107 AND X.status = %s
3108 #AND expiration_time_gmt <= UTC_TIMESTAMP()
3109 AND expiration_time <= UTC_TIMESTAMP()
3110 LIMIT 0, 10
3111 ",
3112 LP_COURSE_CPT,
3113 'enrolled'
3114 );
3115
3116 }
3117
3118 /**
3119 * Add new error log. Support message as an array|object.
3120 * Convert message to string if it is not a string.
3121 *
3122 * @param mixed $value
3123 *
3124 * @since 4.0.0
3125 */
3126 function learn_press_error_log( $value ) {
3127 if ( is_array( $value ) || is_object( $value ) ) {
3128 ob_start();
3129 print_r( $value );
3130 $value = ob_get_clean();
3131 }
3132
3133 error_log( $value );
3134 }
3135
3136 /**
3137 * Get status of global course for current user.
3138 *
3139 * @param int $user_id
3140 * @param int $course_id
3141 *
3142 * @return bool|string
3143 * @since 3.3.0
3144 * @editor tungnx
3145 * @modify 4.1.3 - comment - not use
3146 */
3147 /*function learn_press_user_course_status( $user_id = 0, $course_id = 0 ) {
3148 if ( ! $user = learn_press_get_user( $user_id ? $user_id : get_current_user_id() ) ) {
3149 return false;
3150 }
3151
3152 if ( ! $userCourse = $user->get_course_data( $course_id ) ) {
3153 return false;
3154 }
3155
3156 return $userCourse->get_status();
3157 }*/
3158
3159 /**
3160 * Return list types of questions that support answer options.
3161 *
3162 * @return array
3163 * @since 3.3.0
3164 */
3165 function learn_press_get_question_support_answer_options() {
3166 $questions = learn_press_get_question_support_feature( 'answer-options' );
3167
3168 return apply_filters( 'learn-press/questions-support-answer-options', $questions );
3169 }
3170
3171 /**
3172 * Return list types of question that support a feature.
3173 *
3174 * @param string $feature
3175 *
3176 * @return array
3177 * @since 3.3.0
3178 */
3179 function learn_press_get_question_support_feature( $feature ) {
3180 $questions = array();
3181 $types = LP_Global::get_object_supports( 'question' );
3182
3183 if ( $types ) {
3184 foreach ( $types as $type => $features ) {
3185 if ( array_key_exists( $feature, $features ) ) {
3186 $questions[] = $type;
3187 }
3188 }
3189 }
3190
3191 return $questions;
3192 }
3193
3194 /**
3195 * Helper function to output html for rendering a 'circle progress bar'
3196 *
3197 * @param int $percent
3198 * @param int $width
3199 * @param int $border
3200 * @param string $color
3201 *
3202 * @since 3.3.0
3203 */
3204 function learn_press_circle_progress_html( $percent = 0, $width = 32, $border = 4, $color = '' ) {
3205 $radius = $width / 2;
3206 $r = ( $width - $border ) / 2;
3207 $circumference = $r * 2 * pi();
3208 $offset = $circumference - $percent / 100 * $circumference;
3209
3210 printf(
3211 '<svg class="circle-progress-bar" width="%d" height="%d">
3212 <circle class="circle-progress-bar__circle"
3213 stroke="%s"
3214 stroke-width="%d"
3215 style="stroke-dasharray:%s %s; stroke-dashoffset:%s;"
3216 fill="transparent"
3217 r="%d" cx="%d" cy="%d"></circle>
3218 </svg>',
3219 $width,
3220 $width,
3221 $color,
3222 $border,
3223 $circumference,
3224 $circumference,
3225 $offset,
3226 $r,
3227 $radius,
3228 $radius
3229 );
3230 }
3231
3232 function learn_press_is_page( $page_name ) {
3233 $page_id = learn_press_get_page_id( $page_name );
3234
3235 return $page_id && is_page( $page_id );
3236 }
3237
3238 /**
3239 * Get end-date from start date with a duration.
3240 *
3241 * @param string|int $duration
3242 * @param string|int $start
3243 *
3244 * @return false|string
3245 * @since 3.x.x
3246 */
3247 function learn_press_date_end_from( $duration, $start = '' ) {
3248 $format = 'Y-m-d H:i:s';
3249
3250 if ( ! $start ) {
3251 $start = time();
3252 } elseif ( ! is_numeric( $start ) ) {
3253 $start = strtotime( $start );
3254 }
3255
3256 // is LP duration format, e.g: 10 weeks
3257 if ( preg_match( '/^[0-9]+ [a-z]+$/', $duration ) ) {
3258 $duration = ( new LP_Duration( $duration ) )->get();
3259 } elseif ( ! is_numeric( $duration ) ) {
3260 // 10 days 5 hours ...
3261 $duration = strtotime( $duration, 0 );
3262 }
3263
3264 return date( $format, $start + $duration );
3265 }
3266
3267 function learn_press_date_diff( $from, $to ) {
3268
3269 }
3270
3271 function learn_press_cookie_get( $name, $namespace = 'LP' ) {
3272 if ( $namespace ) {
3273 $cookie = ! empty( $_COOKIE[ $namespace ] ) ? (array) json_decode( LP_Helper::sanitize_params_submitted( stripslashes( $_COOKIE[ $namespace ] ), 'html' ) ) : array();
3274 } else {
3275 $cookie = $_COOKIE;
3276 }
3277
3278 return $cookie[ $name ] ?? null;
3279 }
3280
3281 /**
3282 * Get list of levels support in course.
3283 *
3284 * @return array
3285 * @since 3.x.x
3286 * @editor tungnx
3287 * @reason comment - not use
3288 */
3289 /*
3290 function learn_press_default_course_levels() {
3291 $levels = array(
3292 'beginner' => __( 'Beginner', 'learnpress' ),
3293 'intermediate' => __( 'Intermediate', 'learnpress' ),
3294 'expert' => __( 'Expert', 'learnpress' ),
3295 '' => __( 'All levels', 'learnpress' ),
3296 );
3297
3298 return apply_filters( 'learn-press/default-course-levels', $levels );
3299 }*/
3300
3301 /**
3302 * Get default methods to evaluate course results.
3303 *
3304 * @param string $return - Optional. 'keys' will return keys instead of all.
3305 *
3306 * @return array
3307 * @since 3.x.x
3308 */
3309 function learn_press_course_evaluation_methods( $postid, $return = '', $final_quizz_passing = '' ) {
3310 $course_tip = '<span class="learn-press-tip">%s</span>';
3311 $final_quiz_btn = '<a href="#" class="lp-metabox-get-final-quiz" data-postid="' . $postid . '" data-loading="' . esc_attr__(
3312 'Loading...',
3313 'learnpress'
3314 ) . '">' . esc_html__( 'Get Passing Grade', 'learnpress' ) . '</a>';
3315
3316 $course_desc = array(
3317 'evaluate_lesson' => sprintf(
3318 '<p>%s<br/>%s</p>',
3319 __( 'Evaluate by the number of lessons completed per total number of lessons.', 'learnpress' ),
3320 __( 'E.g: Course has 10 lessons and user completed 5 lessons then the result = 5/10 (50.%)', 'learnpress' )
3321 ),
3322 'evaluate_final_quiz' => __(
3323 'Evaluate by result of final quiz in the course. You have to add a quiz to the end of the course.',
3324 'learnpress'
3325 ),
3326 'evaluate_quiz' => sprintf(
3327 '<p>%s<br/>%s</p>',
3328 __( 'Evaluate by the number of quizzes passed per total number of quizzes.', 'learnpress' ),
3329 __(
3330 'E.g: The course has 10 quizzes and the user passed 5 quizzes then the result = 5/10 (50%).',
3331 'learnpress'
3332 )
3333 ),
3334 'evaluate_questions' => sprintf(
3335 '<p>%s<br/>%s</p>',
3336 __( 'Evaluate by total number of correct answers per total number of questions.', 'learnpress' ),
3337 __(
3338 'E.g: Course has 10 questions. User correct 5 questions. Result is 5/10 (50%).',
3339 'learnpress'
3340 )
3341 ),
3342 'evaluate_mark' => __( 'Evaluate by total score achieved per total score of the questions.', 'learnpress' ),
3343 );
3344
3345 $methods = apply_filters(
3346 'learnpress/course-evaluation/methods',
3347 array(
3348 'evaluate_lesson' => __(
3349 'Evaluate via lessons',
3350 'learnpress'
3351 ) . learn_press_quick_tip( $course_desc['evaluate_lesson'], false ),
3352 'evaluate_final_quiz' => __( 'Evaluate via results of the final quiz', 'learnpress' ) . sprintf(
3353 $course_tip,
3354 $course_desc['evaluate_final_quiz']
3355 ) . $final_quiz_btn . $final_quizz_passing,
3356 'evaluate_quiz' => __( 'Evaluate via quizzes passed', 'learnpress' ) . sprintf(
3357 $course_tip,
3358 $course_desc['evaluate_quiz']
3359 ),
3360 'evaluate_questions' => __( 'Evaluate via questions', 'learnpress' ) . sprintf(
3361 $course_tip,
3362 $course_desc['evaluate_questions']
3363 ),
3364 'evaluate_mark' => __( 'Evaluate via mark', 'learnpress' ) . sprintf(
3365 $course_tip,
3366 $course_desc['evaluate_mark']
3367 ),
3368 )
3369 );
3370
3371 return apply_filters(
3372 'learn-press/course-evaluation-methods',
3373 $return === 'keys' ? array_keys( $methods ) : $methods,
3374 $return
3375 );
3376 }
3377
3378 /**
3379 * Wrap WP Core function current_time with mysql format.
3380 *
3381 * @param bool $gmt
3382 *
3383 * @return int|string
3384 * @since 4.0.0
3385 * @editor tungnx
3386 * @modify 4.1.4.1 - comment - not use
3387 */
3388 /*function learn_press_mysql_time( $gmt = true ) {
3389 return current_time( 'mysql', $gmt );
3390 }*/
3391
3392 /**
3393 * Wrap WP Core function current_time with timestamp format.
3394 *
3395 * @param bool $gmt
3396 *
3397 * @return int|string
3398 * @since 4.0.0
3399 */
3400 function learn_press_timestamp( $gmt = true ) {
3401 return current_time( 'timestamp', $gmt );
3402 }
3403
3404 /**
3405 * Convert time from GMT to local.
3406 *
3407 * @param string|int|LP_Datetime $gmt_time
3408 * @param string $format
3409 *
3410 * @return false|int|string
3411 * @since 4.0.0
3412 */
3413 function learn_press_time_from_gmt( $gmt_time, $format = 'Y-m-d H:i:s' ) {
3414 if ( is_string( $gmt_time ) ) {
3415 $gmt_time = strtotime( $gmt_time );
3416 } elseif ( $gmt_time instanceof LP_Datetime ) {
3417 $gmt_time = strtotime( $gmt_time . '' );
3418 }
3419
3420 $current_time = $gmt_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
3421
3422 if ( $format ) {
3423 return date( $format, $current_time );
3424 }
3425
3426 return $current_time;
3427 }
3428
3429 /**
3430 * Count all users has enrolled courses of an instructor.
3431 *
3432 * @param int $instructor_id . Author of course
3433 *
3434 SELECT COUNT(DISTINCT (user_id)) AS total
3435 FROM wp_learnpress_user_items
3436 WHERE 1 = 1
3437 AND item_type = 'lp_course'
3438 AND item_id IN (
3439 SELECT ID
3440 FROM wp_posts
3441 WHERE post_author = 1
3442 AND post_type = 'lp_course'
3443 AND post_status = 'publish'
3444 );
3445 *
3446 * @return int
3447 * @since 4.0.0
3448 * @editor tungnx
3449 * @version 1.0.1
3450 * @deprecated 4.1.6 replace to "get_statistic_info" function
3451 */
3452 //function learn_press_count_instructor_users( int $instructor_id = 0 ): int {
3453 // try {
3454 // $filter_course = new LP_Course_Filter();
3455 // $filter_course->only_fields = array( 'ID' );
3456 // $filter_course->post_author = $instructor_id;
3457 // $filter_course->post_status = 'publish';
3458 // $filter_course->return_string_query = true;
3459 // $query_courses_str = LP_Course_DB::getInstance()->get_courses( $filter_course );
3460 //
3461 // $filter = new LP_User_Items_Filter();
3462 // $filter->only_fields = array( 'DISTINCT (ui.user_id)' );
3463 // $filter->field_count = 'DISTINCT (ui.user_id)';
3464 // $filter->where[] = "AND item_id IN ({$query_courses_str})";
3465 // $filter->query_count = true;
3466 //
3467 // return LP_User_Item_Course::get_user_courses( $filter );
3468 // //return LP_User_Items_DB::getInstance()->get_user_courses( $filter );
3469 // } catch ( Throwable $e ) {
3470 // error_log( __FUNCTION__ . ': ' . $e->getMessage() );
3471 //
3472 // return 0;
3473 // }
3474 //
3475 // /*$curd = new LP_User_CURD();
3476 // $own_courses = $curd->query_own_courses( $instructor_id );
3477 // $course_ids = $own_courses->get_items();*/
3478 //
3479 // /*
3480 // global $wpdb;
3481 // $filter = new LP_Course_Filter();
3482 // $filter->post_author = $instructor_id;
3483 // $filter->limit = -1;
3484 // $courses = LP_Course::get_courses( $filter );
3485 // $course_ids = LP_Course::get_course_ids( $courses );
3486 //
3487 // if ( ! empty( $course_ids ) ) {
3488 // $query = $wpdb->prepare(
3489 // "
3490 // SELECT COUNT(user_id)
3491 // FROM (
3492 // SELECT item_id, user_id
3493 // FROM {$wpdb->learnpress_user_items}
3494 // WHERE item_type = %s
3495 // GROUP BY item_id, user_id
3496 // HAVING item_id IN(" . join( ',', $course_ids ) . ')
3497 // ) X
3498 // GROUP BY item_id
3499 // ',
3500 // LP_COURSE_CPT
3501 // );
3502 //
3503 // $rows = $wpdb->get_col( $query );
3504 //
3505 // if ( $rows ) {
3506 // return array_sum( $rows );
3507 // }
3508 // }
3509 //
3510 // return 0;*/
3511 //}
3512
3513 /**
3514 * Get max retrying quiz allowed.
3515 *
3516 * @param int $quiz_id
3517 * @param int $course_id
3518 *
3519 * @return int
3520 * @since 4.0.0
3521 */
3522 function learn_press_get_quiz_max_retrying( $quiz_id = 0, $course_id = 0 ) {
3523 return apply_filters( 'learn-press/max-retry-quiz-allowed', 1, $quiz_id, $course_id );
3524 }
3525
3526 /**
3527 * Get max retrying course allowed.
3528 *
3529 * @param int $course_id
3530 *
3531 * @return int
3532 * @since 4.0.0
3533 */
3534 function learn_press_get_course_max_retrying( $course_id ) {
3535 return apply_filters( 'learn-press/max-retry-course-allowed', 1, $course_id );
3536 }
3537
3538 /**
3539 * Get slug for status of course/lesson/quiz if user
3540 * completed/finished and graduation is failed.
3541 *
3542 * @param string $type
3543 *
3544 * @return string
3545 * @since 4.0.0
3546 */
3547 function learn_press_user_item_failed_slug( $type = '' ) {
3548 return apply_filters( 'learn-press/user-item-failed-slug', 'failed', $type );
3549 }
3550
3551 /**
3552 * Get slug for status of course/lesson/quiz if user
3553 * completed/finished and graduation is passed.
3554 *
3555 * @param string $type
3556 *
3557 * @return string
3558 * @since 4.0.0
3559 */
3560 function learn_press_user_item_passed_slug( $type = '' ) {
3561 return apply_filters( 'learn-press/user-item-passed-slug', 'passed', $type );
3562 }
3563
3564 /**
3565 * Get slug for status of course/lesson/quiz if user
3566 * completed/finished and graduation is passed.
3567 *
3568 * @param string $type
3569 *
3570 * @return string
3571 * @since 4.0.0
3572 */
3573 function learn_press_user_item_in_progress_slug( $type = '' ) {
3574 return apply_filters( 'learn-press/user-item-in-progress-slug', 'in-progress', $type );
3575 }
3576
3577 /**
3578 * Get slug for status of course/lesson/quiz if user
3579 * completed/finished and result is under-evaluation
3580 *
3581 * @param string $item - Optional. Type of item
3582 *
3583 * @return string
3584 * @since 4.0.0
3585 */
3586 function learn_press_user_item_under_evaluation_slug( $item = '' ) {
3587 return apply_filters( 'learn-press/user-item-under-evaluation-slug', 'in-progress', $item );
3588 }
3589
3590 function learn_press_is_enrolled_slug( $slug ) {
3591 return in_array(
3592 $slug,
3593 array(
3594 'in-progress',
3595 'enrolled',
3596 )
3597 );
3598 }
3599
3600 /**
3601 * @return array
3602 * @since 4.0.0
3603 * @editor tungnx
3604 * @modify 4.1.3 - comment - not use
3605 */
3606 function learn_press_course_enrolled_slugs(): array {
3607 _deprecated_function( __FUNCTION__, '4.1.3' );
3608 return apply_filters(
3609 'learn-press/course-enrolled-slugs',
3610 array(
3611 learn_press_user_item_passed_slug(),
3612 learn_press_user_item_failed_slug(),
3613 'in-progress',
3614 'enrolled',
3615 'finished', // deprecated
3616 )
3617 );
3618 }
3619
3620 /**
3621 * @return array
3622 * @since 4.0.0
3623 */
3624 function lp_item_course_class( $class = array() ) {
3625 $classes = array_merge(
3626 $class,
3627 array( 'learn-press-courses' )
3628 );
3629 echo 'class="' . esc_attr( implode( ' ', apply_filters( 'lp_item_course_class', $classes ) ) ) . '"';
3630 }
3631
3632 //require_once dirname( __FILE__ ) . '/lp-custom-hooks.php';
3633
3634
3635 /**
3636 * Disable auto update
3637 *
3638 * @param $update
3639 * @param $item
3640 *
3641 * @return false
3642 * @author hungkv
3643 */
3644 /*function learnpress_disable_auto_update( $update, $item ) {
3645 $plugins = array( // Plugins to auto-update
3646 'learnpress',
3647 );
3648 // Auto-update specified plugins
3649 if ( in_array( $item->slug, $plugins ) ) {
3650 return false;
3651 }
3652 }
3653 add_filter( 'auto_update_plugin', 'learnpress_disable_auto_update', 10, 2 );*/
3654
3655 add_action(
3656 'in_plugin_update_message-learnpress/learnpress.php',
3657 function ( $plugin_data ) {
3658 version_update_warning( LEARNPRESS_VERSION, $plugin_data['new_version'] );
3659 }
3660 );
3661 /**
3662 * Custom message warning have new version
3663 *
3664 * @param $current_version
3665 * @param $new_version
3666 * @author hungkv
3667 */
3668 function version_update_warning( $current_version, $new_version ) {
3669 $current_version_minor_part = explode( '.', $current_version )[1];
3670 $new_version_minor_part = explode( '.', $new_version )[1];
3671 if ( $current_version_minor_part === $new_version_minor_part ) {
3672 return;
3673 }
3674
3675 $info = get_plugin_data( LP_PLUGIN_FILE );
3676 ?>
3677 <hr class="lp-update--warning__separator"/>
3678 <div class="lp-update--warning">
3679 <div>
3680 <div class="lp-update-warning__title">
3681 <?php echo esc_html__( 'Heads up, Please backup before upgrade!', 'learnpress' ); ?>
3682 </div>
3683 <div class="lp-update-warning__message">
3684 <?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' ); ?>
3685 <?php echo esc_html__( 'Learners require WordPress version ' . $info['Requires at least'] . ' or higher.', 'learnpress' ); ?>
3686 </div>
3687 </div>
3688 </div>
3689
3690 <?php
3691 }
3692
3693 // If profile content don't have shortcode profile.
3694 function lp_add_shortcode_profile() {
3695 global $post;
3696
3697 if ( learn_press_is_profile() && is_object( $post ) ) {
3698 if ( ! has_shortcode( $post->post_content, 'learn_press_profile' ) ) {
3699 $post->post_content .= '<!-- wp:shortcode -->[' . apply_filters( 'learn-press/shortcode/profile/tag', 'learn_press_profile' ) . ']<!-- /wp:shortcode -->';
3700 }
3701
3702 wp_update_post( $post );
3703 }
3704 }
3705
3706 add_action( 'template_redirect', 'lp_add_shortcode_profile' );
3707
3708 /**
3709 * If Elementor Pro set Theme builder type "Archive", will not show content on page "Archive course"
3710 *
3711 * @editor tungnx
3712 * @author nhamdv
3713 *
3714 * @since 4.0.6
3715 * @version 1.0.1
3716 */
3717 add_filter(
3718 'elementor/theme/get_location_templates/template_id',
3719 function( $theme_template_id ) {
3720 $elementor_template_type = get_post_meta( $theme_template_id, '_elementor_template_type', true );
3721
3722 if ( in_array( $elementor_template_type, array( 'archive' ) ) ) {
3723 if ( LP_PAGE_COURSES === LP_Page_Controller::page_current() && class_exists( 'ElementorPro\Modules\ThemeBuilder\Conditions\Archive' ) ) {
3724 return false;
3725 }
3726 }
3727
3728 return $theme_template_id;
3729 }
3730 );
3731