PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/lp-core-functions.php +2338 -2337 4.3.94.4.8 View file →
@@ -1,2337 +1,2338 @@
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 -use LearnPress\Helpers\Config;
12 -
13 -defined( 'ABSPATH' ) || exit;
14 -
15 -/**
16 - * Vue write php has script, so when sanitize will error, so use code is mask pass check sanitize, esc
17 - *
18 - * @param $content
19 - *
20 - * @return void
21 - * @since 4.1.6.9
22 - */
23 -function learn_press_echo_vuejs_write_on_php( $content ) {
24 - echo ( $content );
25 -}
26 -
27 -function learnpress_gutenberg_disable_cpt( $can_edit, $post_type ) {
28 - $post_types = array(
29 - LP_COURSE_CPT => LP_Settings::get_option( 'enable_gutenberg_course', 'no' ),
30 - LP_LESSON_CPT => LP_Settings::get_option( 'enable_gutenberg_lesson', 'no' ),
31 - LP_QUIZ_CPT => LP_Settings::get_option( 'enable_gutenberg_quiz', 'no' ),
32 - LP_QUESTION_CPT => LP_Settings::get_option( 'enable_gutenberg_question', 'no' ),
33 - );
34 -
35 - foreach ( $post_types as $key => $pt ) {
36 - if ( $post_type === $key && $pt !== 'yes' ) {
37 - $can_edit = false;
38 - }
39 - }
40 -
41 - return $can_edit;
42 -}
43 -add_filter( 'use_block_editor_for_post_type', 'learnpress_gutenberg_disable_cpt', 10, 2 );
44 -
45 -if ( ! function_exists( 'lp_add_body_class' ) ) {
46 - function lp_add_body_class( $classes ) {
47 - $classes = (array) $classes;
48 -
49 - if ( LP_Page_Controller::is_page_profile() ) {
50 - $classes[] = 'learnpress-profile';
51 - } elseif ( learn_press_is_checkout() ) {
52 - $classes[] = 'learnpress-checkout';
53 - }
54 -
55 - return $classes;
56 - }
57 - add_filter( 'body_class', 'lp_add_body_class' );
58 -}
59 -
60 -/**
61 - * Short function to get name of a theme
62 - *
63 - * @param string $folder
64 - *
65 - * @return mixed|string
66 - */
67 -function learn_press_get_theme_name( $folder ) {
68 - $theme = wp_get_theme( $folder );
69 -
70 - return ! empty( $theme['Name'] ) ? $theme['Name'] : '';
71 -}
72 -
73 -/**
74 - * Clean.
75 - *
76 - * @param [type] $var
77 - *
78 - * @version 4.0.0
79 - * @author Nhamdv <daonham95@gmail.com>
80 - */
81 -function learnpress_clean( $var ) {
82 - if ( is_array( $var ) ) {
83 - return array_map( 'learnpress_clean', $var );
84 - } else {
85 - return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
86 - }
87 -}
88 -
89 -/**
90 - * Display HTML of element for building QuickTip JS.
91 - *
92 - * @param string $tip
93 - * @param bool $echo
94 - * @param array $options
95 - *
96 - * @return string
97 - * @since 3.0.0
98 - */
99 -function learn_press_quick_tip( $tip, $echo = true, $options = array() ) {
100 - $atts = '';
101 - if ( $options ) {
102 - foreach ( $options as $k => $v ) {
103 - $options[ $k ] = "data-{$k}=\"{$v}\"";
104 - }
105 - $atts = ' ' . implode( ' ', $options );
106 - }
107 -
108 - $tip = sprintf( '<div class="learn-press-tip" ' . $atts . '><span>%s</span></div>', $tip );
109 -
110 - if ( $echo ) {
111 - echo wp_kses_post( $tip );
112 - }
113 -
114 - return $tip;
115 -}
116 -
117 -/**
118 - * Get current post ID.
119 - *
120 - * @return int
121 - */
122 -function learn_press_get_post() {
123 - global $post;
124 -
125 - $post_id = learn_press_get_request( 'post' );
126 -
127 - if ( ! $post_id ) {
128 - $post_id = ! empty( $post ) ? $post->ID : 0;
129 - }
130 - if ( empty( $post_id ) ) {
131 - $post_id = learn_press_get_request( 'post_ID' );
132 - }
133 -
134 - return absint( $post_id );
135 -}
136 -
137 -/**
138 - * Get the LearnPress plugin url
139 - *
140 - * @param string $sub_dir
141 - *
142 - * @return string
143 - */
144 -function learn_press_plugin_url( $sub_dir = '' ) {
145 - return LearnPress::instance()->plugin_url( $sub_dir );
146 -}
147 -
148 -/**
149 - * Get the LearnPress plugin path.
150 - *
151 - * @param string $sub_dir
152 - *
153 - * @return string
154 - */
155 -function learn_press_plugin_path( $sub_dir = '' ) {
156 - return LearnPress::instance()->plugin_path( $sub_dir );
157 -}
158 -
159 -/**
160 - * Includes file base on LearnPress path
161 - *
162 - * @param string $file
163 - * @param string $folder
164 - * @param bool $include_once
165 - *
166 - * @return bool
167 - */
168 -function learn_press_include( $file, $folder = 'inc', $include_once = true ) {
169 - $include = learn_press_plugin_path( "{$folder}/{$file}" );
170 -
171 - if ( file_exists( $include ) ) {
172 - if ( $include_once ) {
173 - include_once $include;
174 - } else {
175 - include $include;
176 - }
177 -
178 - return true;
179 - }
180 -
181 - return false;
182 -}
183 -
184 -/**
185 - * Get current IP of the user
186 - *
187 - * @return mixed
188 - */
189 -function learn_press_get_ip() {
190 - if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
191 - return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) );
192 - } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
193 - // Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
194 - // Make sure we always only send through the first IP in the list which should always be the client IP.
195 - return (string) rest_is_ip_address( trim( current( preg_split( '/,/', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) );
196 - } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
197 - return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
198 - }
199 - return '';
200 -}
201 -
202 -/**
203 - * Get user agent.
204 - *
205 - * @return string
206 - */
207 -function learn_press_get_user_agent(): string {
208 - return LP_Helper::sanitize_params_submitted( $_SERVER['HTTP_USER_AGENT'] ?? '' );
209 -}
210 -
211 -/**
212 - * Generate an unique string.
213 - *
214 - * @param string $prefix
215 - *
216 - * @return string
217 - */
218 -function learn_press_uniqid( $prefix = '' ) {
219 - $hash = str_replace( '.', '', microtime( true ) . uniqid() );
220 -
221 - return apply_filters( 'learn-press/generate-hash', $prefix . $hash, $prefix );
222 -}
223 -
224 -function learn_press_random_value( $len = 8 ) {
225 - return substr( md5( uniqid( mt_rand(), true ) ), 0, $len );
226 -}
227 -
228 -function learn_press_map_columns_format( $columns, $format ) {
229 - $return = array();
230 - foreach ( $columns as $k => $v ) {
231 - if ( ! empty( $format[ $k ] ) ) {
232 - $return[] = $format[ $k ];
233 - } else {
234 - $return[] = '%s'; // default is string
235 - }
236 - }
237 -
238 - return $return;
239 -}
240 -
241 -/**
242 - * Check to see if an endpoint is showing in current URL.
243 - *
244 - * @param bool $endpoint
245 - *
246 - * @return bool
247 - */
248 -function learn_press_is_endpoint_url( $endpoint = false ) {
249 - global $wp;
250 -
251 - $endpoints = array();
252 -
253 - if ( $endpoint !== false ) {
254 - if ( ! isset( $endpoints[ $endpoint ] ) ) {
255 - return false;
256 - } else {
257 - $endpoint_var = $endpoints[ $endpoint ];
258 - }
259 -
260 - return isset( $wp->query_vars[ $endpoint_var ] );
261 - } else {
262 - foreach ( $endpoints as $key => $value ) {
263 - if ( isset( $wp->query_vars[ $key ] ) ) {
264 - return true;
265 - }
266 - }
267 -
268 - return false;
269 - }
270 -}
271 -
272 -/**
273 - * Get current URL user is viewing.
274 - *
275 - * @return string
276 - * @deprecated 4.2.2
277 - */
278 -function learn_press_get_current_url() {
279 - //_deprecated_function( __FUNCTION__, '4.2.2', 'LP_Helper::getUrlCurrent' );
280 - return LP_Helper::getUrlCurrent();
281 -
282 - $url = untrailingslashit( esc_url_raw( $_SERVER['REQUEST_URI'] ) );
283 -
284 - if ( ! preg_match( '!^https?!', $url ) ) {
285 - $siteurl = trailingslashit( get_home_url() );
286 - $home_query = '';
287 -
288 - if ( strpos( $siteurl, '?' ) !== false ) {
289 - $parts = explode( '?', $siteurl );
290 - $home_query = $parts[1];
291 - $siteurl = $parts[0];
292 - }
293 -
294 - if ( $home_query ) {
295 - parse_str( untrailingslashit( $home_query ), $home_query );
296 - $url = esc_url_raw( add_query_arg( $home_query, $url ) );
297 - }
298 -
299 - $segs1 = explode( '/', $siteurl );
300 - $segs2 = explode( '/', $url );
301 -
302 - if ( $removed = array_intersect( $segs1, $segs2 ) ) {
303 - if ( $segs2 = array_diff( $segs2, $removed ) ) {
304 - $current_url = $siteurl . join( '/', $segs2 );
305 - if ( strpos( $current_url, '?' ) === false ) {
306 - $current_url = trailingslashit( $current_url );
307 - }
308 - }
309 - }
310 - }
311 -
312 - return $current_url;
313 -}
314 -
315 -/**
316 - * Remove unneeded characters in an URL
317 - *
318 - * @param string $url
319 - * @param bool $trailingslashit
320 - *
321 - * @return string
322 - */
323 -function learn_press_sanitize_url( $url, $trailingslashit = true ) {
324 - if ( $url ) {
325 - preg_match( '!(https?://)?(.*)!', $url, $matches );
326 - $url_without_http = $matches[2];
327 - $url_without_http = preg_replace( '![/]+!', '/', $url_without_http );
328 - $url = $matches[1] . $url_without_http;
329 -
330 - return ( $trailingslashit &&
331 - strpos( $url, '?' ) === false ) ? trailingslashit( $url ) : untrailingslashit( $url );
332 - }
333 -
334 - return $url;
335 -}
336 -
337 -/**
338 - * Get all types of question supported
339 - *
340 - * @return mixed
341 - */
342 -function learn_press_question_types() {
343 - return LP_Question::get_types();
344 -}
345 -
346 -/**
347 - * Get human name of question's type by slug
348 - *
349 - * @param string $slug
350 - *
351 - * @return array
352 - */
353 -function learn_press_question_name_from_slug( $slug ) {
354 - $types = learn_press_question_types();
355 - $name = ! empty( $types[ $slug ] ) ? $types[ $slug ] : '';
356 -
357 - return apply_filters( 'learn-press/question/slug-to-name', $name, $slug );
358 -}
359 -
360 -/**
361 - * Get terms of a course by taxonomy.
362 - * E.g: course_tag, course_category
363 - *
364 - * @param int $course_id
365 - * @param string $taxonomy
366 - * @param array $args
367 - *
368 - * @return array|mixed
369 - */
370 -function learn_press_get_course_terms( $course_id, $taxonomy, $args = array() ) {
371 - if ( ! taxonomy_exists( $taxonomy ) ) {
372 - return array();
373 - }
374 -
375 - // Support ordering by parent
376 - if ( ! empty( $args['orderby'] ) && in_array( $args['orderby'], array( 'name_num', 'parent' ) ) ) {
377 - $fields = isset( $args['fields'] ) ? $args['fields'] : 'all';
378 - $orderby = $args['orderby'];
379 -
380 - // Unset for wp_get_post_terms
381 - unset( $args['orderby'] );
382 - unset( $args['fields'] );
383 -
384 - $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
385 -
386 - switch ( $orderby ) {
387 - case 'name_num':
388 - usort( $terms, '_learn_press_get_course_terms_name_num_usort_callback' );
389 - break;
390 - case 'parent':
391 - usort( $terms, '_learn_press_get_course_terms_parent_usort_callback' );
392 - break;
393 - }
394 -
395 - switch ( $fields ) {
396 - case 'names':
397 - $terms = wp_list_pluck( $terms, 'name' );
398 - break;
399 - case 'ids':
400 - $terms = wp_list_pluck( $terms, 'term_id' );
401 - break;
402 - case 'slugs':
403 - $terms = wp_list_pluck( $terms, 'slug' );
404 - break;
405 - }
406 - } elseif ( ! empty( $args['orderby'] ) && $args['orderby'] === 'menu_order' ) {
407 - // wp_get_post_terms doesn't let us use custom sort order
408 - $args['include'] = wp_get_post_terms( $course_id, $taxonomy, array( 'fields' => 'ids' ) );
409 -
410 - if ( empty( $args['include'] ) ) {
411 - $terms = array();
412 - } else {
413 - // This isn't needed for get_terms
414 - unset( $args['orderby'] );
415 -
416 - // Set args for get_terms
417 - $args['menu_order'] = $args['order'] ?? 'ASC';
418 - $args['hide_empty'] = $args['hide_empty'] ?? 0;
419 - $args['fields'] = $args['fields'] ?? 'names';
420 -
421 - // Ensure slugs is valid for get_terms - slugs isn't supported
422 - $args['fields'] = $args['fields'] === 'slugs' ? 'id=>slug' : $args['fields'];
423 - $terms = get_terms( $taxonomy, $args );
424 - }
425 - } else {
426 - $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
427 - }
428 -
429 - // @deprecated
430 - $terms = apply_filters( 'learn_press_get_course_terms', $terms, $course_id, $taxonomy, $args );
431 -
432 - return apply_filters( 'learn-press/course/terms', $terms, $course_id, $taxonomy, $args );
433 -}
434 -
435 -/**
436 - * Callback function for sorting terms of course by name.
437 - *
438 - * @param object $a
439 - * @param object $b
440 - *
441 - * @return int
442 - */
443 -function _learn_press_get_course_terms_name_num_usort_callback( $a, $b ) {
444 - if ( $a->name + 0 === $b->name + 0 ) {
445 - return 0;
446 - }
447 -
448 - return ( $a->name + 0 < $b->name + 0 ) ? - 1 : 1;
449 -}
450 -
451 -/**
452 - * Callback function for sorting terms of course by parent.
453 - *
454 - * @param object $a
455 - * @param object $b
456 - *
457 - * @return int
458 - */
459 -function _learn_press_get_course_terms_parent_usort_callback( $a, $b ) {
460 - if ( $a->parent === $b->parent ) {
461 - return 0;
462 - }
463 -
464 - return ( $a->parent < $b->parent ) ? 1 : - 1;
465 -}
466 -
467 -/**
468 - * Get posts by it's post-name (slug).
469 - *
470 - * @param string $name
471 - * @param string $type
472 - * @param bool $single
473 - *
474 - * @return array|bool|null|WP_Post
475 - */
476 -function learn_press_get_post_by_name( $name, $type, $single = true ) {
477 - $post_name = sanitize_title( $name );
478 - $id = LP_Object_Cache::get( $type . '-' . $post_name, 'learn-press/post-names' );
479 -
480 - if ( false === $id ) {
481 - foreach ( array( $name, urldecode( $name ) ) as $_name ) {
482 - $args = array(
483 - 'name' => $_name,
484 - 'post_type' => array( $type ),
485 - );
486 -
487 - $posts = get_posts( $args );
488 -
489 - if ( $posts ) {
490 - $post = $posts[0];
491 - $id = $post->ID;
492 - wp_cache_set( $id, $post, 'posts' );
493 - LP_Object_Cache::set( $type . '-' . $name, $id, 'learn-press/post-names' );
494 - break;
495 - }
496 - }
497 - }
498 -
499 - return $id ? get_post( $id ) : false;
500 -}
501 -
502 -if ( ! function_exists( 'learn_press_is_ajax' ) ) {
503 - function learn_press_is_ajax() {
504 - return defined( 'LP_DOING_AJAX' ) && LP_DOING_AJAX && 'yes' != learn_press_get_request( 'noajax' );
505 - }
506 -}
507 -
508 -/**
509 - * Get page id from admin settings page
510 - *
511 - * @param string $name
512 - *
513 - * @since 3.0.0
514 - * @version 1.0.2
515 - * @return int
516 - */
517 -function learn_press_get_page_id( string $name ): int {
518 - $page_id = LP_Settings::get_option( "{$name}_page_id", false );
519 -
520 - /*if ( function_exists( 'icl_object_id' ) ) {
521 - $page_id = icl_object_id( $page_id, 'page', false, defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : '' );
522 - }*/
523 -
524 - $page_id = (int) $page_id;
525 -
526 - return apply_filters( 'learn_press_get_page_id', $page_id, $name );
527 -}
528 -
529 -/**
530 - * display the seconds in time format h:i:s
531 - *
532 - * @param $seconds
533 - * @param string $separator
534 - *
535 - * @return string
536 - */
537 -function learn_press_seconds_to_time( $seconds, $separator = ':' ) {
538 - return sprintf(
539 - '%02d%s%02d%s%02d',
540 - floor( $seconds / 3600 ),
541 - $separator,
542 - ( $seconds / 60 ) % 60,
543 - $separator,
544 - $seconds % 60
545 - );
546 -}
547 -
548 -/* nav */
549 -if ( ! function_exists( 'learn_press_course_paging_nav' ) ) {
550 -
551 - /**
552 - * Display navigation to next/previous set of posts when applicable.
553 - *
554 - * @param array
555 - */
556 - function learn_press_course_paging_nav( $args = array() ) {
557 - learn_press_paging_nav(
558 - array(
559 - 'num_pages' => $GLOBALS['wp_query']->max_num_pages,
560 - 'wrapper_class' => 'navigation pagination',
561 - )
562 - );
563 - }
564 -}
565 -
566 -/* nav */
567 -if ( ! function_exists( 'learn_press_paging_nav' ) ) {
568 - function learn_press_paging_nav( $args = array() ) {
569 - $args = wp_parse_args(
570 - $args,
571 - array(
572 - 'num_pages' => 0,
573 - 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
574 - 'wrapper_class' => 'learn-press-pagination',
575 - 'base' => false,
576 - 'format' => '',
577 - 'echo' => true,
578 - )
579 - );
580 -
581 - if ( $args['num_pages'] < 2 ) {
582 - return false;
583 - }
584 -
585 - $paged = $args['paged'];
586 - $pagenum_link = html_entity_decode( $args['base'] === false ? get_pagenum_link() : $args['base'] );
587 -
588 - $query_args = array();
589 - $url_parts = explode( '?', $pagenum_link );
590 -
591 - if ( isset( $url_parts[1] ) ) {
592 - wp_parse_str( $url_parts[1], $query_args );
593 - }
594 -
595 - $pagenum_link = esc_url_raw( remove_query_arg( array_keys( $query_args ), $pagenum_link ) );
596 - $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
597 -
598 - $format = $GLOBALS['wp_rewrite']->using_index_permalinks() && ! strpos(
599 - $pagenum_link,
600 - 'index.php'
601 - ) ? 'index.php/' : '';
602 - $format .= $args['format'] ? $args['format'] : ( $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit(
603 - 'page/%#%',
604 - 'paged'
605 - ) : '?paged=%#%' );
606 -
607 - $link_args = array(
608 - 'base' => $pagenum_link,
609 - 'format' => $format,
610 - 'total' => $args['num_pages'],
611 - 'current' => max( 1, $paged ),
612 - 'mid_size' => 1,
613 - 'add_args' => array_map( 'urlencode', $query_args ),
614 - 'prev_text' => __( '<', 'learnpress' ),
615 - 'next_text' => __( '>', 'learnpress' ),
616 - 'type' => 'list',
617 - );
618 -
619 - // Set up paginated links.
620 - $links = paginate_links( $link_args );
621 -
622 - ob_start();
623 -
624 - if ( $links ) {
625 - ?>
626 - <div class="<?php echo esc_attr( $args['wrapper_class'] ); ?>">
627 - <?php echo wp_kses_post( $links ); ?>
628 - </div>
629 - <?php
630 - }
631 -
632 - $output = ob_get_clean();
633 -
634 - if ( $args['echo'] ) {
635 - echo wp_kses_post( $output );
636 - }
637 -
638 - return $output;
639 - }
640 -}
641 -
642 -/**
643 - * Get number of pages by rows and items per page.
644 - *
645 - * @param int $total
646 - * @param int $limit
647 - *
648 - * @return int
649 - */
650 -function learn_press_get_num_pages( $total, $limit = 10 ) {
651 - $limit = $limit <= 0 ? 10 : $limit;
652 -
653 - if ( $total <= $limit ) {
654 - return 1;
655 - }
656 -
657 - $pages = absint( $total / $limit );
658 -
659 - if ( $total % $limit != 0 ) {
660 - ++$pages;
661 - }
662 -
663 - return $pages;
664 -}
665 -
666 -/**
667 - * Get text
668 - *
669 - * @param $status_id
670 - *
671 - * @return mixed
672 - */
673 -function learn_press_get_status_text( $status_id ) {
674 - switch ( $status_id ) {
675 - case 1:
676 - $text = 'pending';
677 - break;
678 - case 2:
679 - $text = 'complete';
680 - break;
681 - case - 1:
682 - $text = 'cancel';
683 - break;
684 - case - 2:
685 - $text = 'refund';
686 - break;
687 - default:
688 - $text = 'on-hold';
689 - }
690 -
691 - return $text;
692 -}
693 -
694 -function learn_press_get_course_duration_support() {
695 - return apply_filters(
696 - 'learn_press_course_duration_support',
697 - array(
698 - 'minute' => esc_html__( 'Minute(s)', 'learnpress' ),
699 - 'hour' => esc_html__( 'Hour(s)', 'learnpress' ),
700 - 'day' => esc_html__( 'Day(s)', 'learnpress' ),
701 - 'week' => esc_html__( 'Week(s)', 'learnpress' ),
702 - )
703 - );
704 -}
705 -
706 -function learn_press_number_to_string_time( $number ) {
707 - $str = $number;
708 -
709 - if ( preg_match( '!([0-9.]+) (minute|hour|day|week)!', $number, $matches ) ) {
710 - switch ( $matches[2] ) {
711 - case 'hour':
712 - $minute = $matches[1] * 60;
713 - $str = sprintf( '%s hour %s minute', absint( $minute / 60 ), $minute % 60 );
714 - break;
715 - case 'day':
716 - $hour = $matches[1] * 24;
717 - $str = sprintf( '%s day %s hour', absint( $hour / 24 ), $hour % 24 );
718 - break;
719 - case 'week':
720 - $day = $matches[1] * 7;
721 - $str = sprintf( '%s week %s day', absint( $day / 7 ), $day % 7 );
722 - break;
723 - }
724 - }
725 -
726 - return $str;
727 -}
728 -
729 -function learn_press_human_time_to_seconds( $time, $default = '' ) {
730 - $duration = learn_press_get_course_duration_support();
731 - $duration_keys = array_keys( $duration );
732 -
733 - if ( preg_match_all( '!([0-9]+)\s*(' . join( '|', $duration_keys ) . ')?!', $time, $matches ) ) {
734 - $a1 = $matches[1][0];
735 - $a2 = in_array( $matches[2][0], $duration_keys ) ? $matches[2][0] : '';
736 - } else {
737 - $a1 = absint( $time );
738 - $a2 = '';
739 - }
740 -
741 - if ( $a2 ) {
742 - $b = array(
743 - 'minute' => 60,
744 - 'hour' => 3600,
745 - 'day' => 3600 * 24,
746 - 'week' => 3600 * 24 * 7,
747 - );
748 - $a1 = $a1 * $b[ $a2 ];
749 - }
750 -
751 - return $a1;
752 -}
753 -
754 -/**
755 - * @param $user_id
756 - *
757 - * @return WP_Query
758 - */
759 -function learn_press_get_own_courses( $user_id ) {
760 - $arr_query = array(
761 - 'post_type' => 'lp_course',
762 - 'author' => $user_id,
763 - 'post_status' => 'publish',
764 - 'ignore_sticky_posts' => true,
765 - 'posts_per_page' => - 1,
766 - );
767 - $my_query = new WP_Query( $arr_query );
768 -
769 - return $my_query;
770 -}
771 -
772 -/**
773 - * Return array list of currency positions.
774 - *
775 - * @param bool|string $currency
776 - *
777 - * @return array
778 - */
779 -function learn_press_currency_positions( $currency = false ) {
780 - $positions = array(
781 - 'left' => __( 'Left', 'learnpress' ),
782 - 'right' => __( 'Right', 'learnpress' ),
783 - 'left_with_space' => __( 'Left with space', 'learnpress' ),
784 - 'right_with_space' => __( 'Right with space', 'learnpress' ),
785 - );
786 -
787 - if ( false === $currency ) {
788 - $currency = learn_press_get_currency_symbol();
789 - }
790 -
791 - $settings = LP_Settings::instance();
792 -
793 - $thousands_separator = '';
794 - $decimals_separator = $settings->get( 'decimals_separator', '.' );
795 - $number_of_decimals = $settings->get( 'number_of_decimals', 2 );
796 -
797 - if ( $number_of_decimals > 0 ) {
798 - $example = '69' . $decimals_separator . str_repeat( '9', $number_of_decimals );
799 - } else {
800 - $example = '69';
801 - }
802 -
803 - foreach ( $positions as $pos => $text ) {
804 - switch ( $pos ) {
805 - case 'left':
806 - $text = sprintf( '%s ( %s%s )', $text, $currency, $example );
807 - break;
808 - case 'right':
809 - $text = sprintf( '%s ( %s%s )', $text, $example, $currency );
810 - break;
811 - case 'left_with_space':
812 - $text = sprintf( '%s ( %s %s )', $text, $currency, $example );
813 - break;
814 - case 'right_with_space':
815 - $text = sprintf( '%s ( %s %s )', $text, $example, $currency );
816 - break;
817 - }
818 - $positions[ $pos ] = $text;
819 - }
820 -
821 - $positions = apply_filters( 'learn_press_currency_positions', $positions );
822 -
823 - return apply_filters( 'learn-press/currency-positions', $positions );
824 -}
825 -
826 -/**
827 - * @return array
828 - */
829 -function learn_press_get_payment_currencies() {
830 - return apply_filters( 'learn_press_get_payment_currencies', learn_press_currencies() );
831 -}
832 -
833 -/**
834 - * Get the list of currencies with code and name.
835 - *
836 - * @return array
837 - * @version 3.0.1
838 - *
839 - * @author ThimPress
840 - */
841 -function learn_press_currencies() {
842 - return Config::instance()->get( 'currencies', 'settings' );
843 -}
844 -
845 -/**
846 - * Return list of common symbols of the currencies on the world.
847 - *
848 - * @return array
849 - * @version 3.0.1
850 - */
851 -function learn_press_currency_symbols() {
852 - return Config::instance()->get( 'currency-symbols', 'settings' );
853 -}
854 -
855 -/**
856 - * Get current setting of currency.
857 - *
858 - * @return string
859 - */
860 -function learn_press_get_currency(): string {
861 - $currency = LP_Settings::instance()->get( 'currency', 'USD' );
862 -
863 - return esc_html( apply_filters( 'learn-press/currency', $currency ) );
864 -}
865 -
866 -/**
867 - * Return currency symbol from the code.
868 - *
869 - * @param string $currency
870 - *
871 - * @return string
872 - */
873 -function learn_press_get_currency_symbol( $currency = '' ) {
874 - if ( ! $currency ) {
875 - $currency = learn_press_get_currency();
876 - }
877 - $symbols = learn_press_currency_symbols();
878 - $currency_symbol = $symbols[ $currency ] ?? '';
879 -
880 - $currency_symbol = apply_filters( 'learn_press_currency_symbol', $currency_symbol, $currency );
881 -
882 - return apply_filters( 'learn-press/currency-symbol', $currency_symbol, $currency );
883 -}
884 -
885 -/**
886 - * Get static page for LP page by name.
887 - *
888 - * @param string $key
889 - *
890 - * @return string
891 - * @editor tungnx
892 - * @modify 4.1.4
893 - */
894 -function learn_press_get_page_link( string $key ): string {
895 - $page_id = learn_press_get_page_id( $key );
896 - $key_cache = "lp/page-link/{$key}";
897 - $link = LP_Cache::cache_load_first( 'get', $key_cache );
898 - if ( false !== $link ) {
899 - return $link;
900 - }
901 -
902 - if ( $page_id && get_post_status( $page_id ) == 'publish' ) {
903 - $permalink = get_permalink( $page_id );
904 - $link = apply_filters( 'learn-press/get-page-link', trailingslashit( $permalink ), $page_id, $key );
905 - LP_Cache::cache_load_first( 'set', $key_cache, $link );
906 - }
907 -
908 - return $link;
909 -}
910 -
911 -/**
912 - * Get static page for LP page by name.
913 - *
914 - * @param string $key
915 - *
916 - * @return string
917 - */
918 -function learn_press_get_page_title( $key ) {
919 - $page_id = LP_Settings::instance()->get( $key . '_page_id' );
920 - $title = '';
921 -
922 - if ( $page_id && get_post_status( $page_id ) == 'publish' ) {
923 - $title = apply_filters( 'learn-press/get-page-title', get_the_title( $page_id ), $page_id, $key );
924 - }
925 -
926 - return apply_filters( 'learn-press/get-page-' . $key . '-title', $title, $page_id );
927 -}
928 -
929 -/**
930 - * get the ID of a course by order ID
931 - *
932 - * @param $order_id
933 - *
934 - * @return bool|mixed
935 - */
936 -function learn_press_get_course_by_order( $order_id ) {
937 - $order_items = get_post_meta( $order_id, '_learn_press_order_items', true );
938 -
939 - if ( $order_items && $order_items->products ) {
940 - $array_keys = array_keys( $order_items->products );
941 -
942 - return reset( $array_keys );
943 - }
944 -
945 - return false;
946 -}
947 -
948 -/**
949 - * Convert a number of seconds to weeks/days/hours.
950 - *
951 - * @param int $secs
952 - *
953 - * @return bool|string
954 - */
955 -function learn_press_seconds_to_weeks( int $secs = 0 ) {
956 - $secs = (int) $secs;
957 -
958 - if ( 0 === $secs ) {
959 - return false;
960 - }
961 - // variables for holding values.
962 - $mins = 0;
963 - $hours = 0;
964 - $days = 0;
965 - $weeks = 0;
966 - // calculations.
967 - if ( $secs >= 60 ) {
968 - $mins = (int) ( $secs / 60 );
969 - $secs = $secs % 60;
970 - }
971 - if ( $mins >= 60 ) {
972 - $hours = (int) ( $mins / 60 );
973 - $mins = $mins % 60;
974 - }
975 - if ( $hours >= 24 ) {
976 - $days = (int) ( $hours / 24 );
977 - $hours = $hours % 24;
978 - }
979 - if ( $days >= 7 ) {
980 - $weeks = (int) ( $days / 7 );
981 - $days = $days % 7;
982 - }
983 - // format result.
984 - $result = '';
985 - if ( $weeks ) {
986 - $result .= sprintf( _n( '%s week', '%s weeks', $weeks, 'learnpress' ), $weeks ) . ' ';
987 - }
988 -
989 - if ( $days ) {
990 - $result .= sprintf( _n( '%s day', '%s days', $days, 'learnpress' ), $days ) . ' ';
991 - }
992 -
993 - if ( ! $weeks ) {
994 - if ( $hours ) {
995 - $result .= sprintf( _n( '%s hour', '%s hours', $hours, 'learnpress' ), $hours ) . ' ';
996 - }
997 -
998 - if ( $mins ) {
999 - $result .= sprintf( _n( '%s minute', '%s minutes', $mins, 'learnpress' ), $mins ) . ' ';
1000 - }
1001 - }
1002 -
1003 - $result = rtrim( $result );
1004 -
1005 - return $result;
1006 -}
1007 -
1008 -function learn_press_user_maybe_is_a_teacher( $user = null ) {
1009 - if ( ! $user ) {
1010 - $user = learn_press_get_current_user();
1011 - } elseif ( is_numeric( $user ) ) {
1012 - $user = learn_press_get_user( $user );
1013 - }
1014 - if ( ! $user || $user instanceof LP_User_Guest ) {
1015 - return false;
1016 - }
1017 -
1018 - $role = $user->has_role( 'administrator' ) ? 'administrator' : false;
1019 - if ( ! $role ) {
1020 - $role = $user->has_role( 'lp_teacher' ) ? 'lp_teacher' : false;
1021 - }
1022 -
1023 - return apply_filters( 'learn-press/user/is-teacher', $role, $user->get_id() );
1024 -}
1025 -
1026 -function learn_press_become_teacher_sent( $user_id = 0 ) {
1027 - if ( func_num_args() == 0 ) {
1028 - $user_id = get_current_user_id();
1029 - }
1030 -
1031 - return 'yes' === get_user_meta( $user_id, '_requested_become_teacher', true );
1032 -}
1033 -
1034 -function _learn_press_translate_user_roles( $translations, $text, $context, $domain ) {
1035 - $plugin_domain = 'learnpress';
1036 - $roles = array( 'LP Instructor' );
1037 -
1038 - if ( $context === 'User role' && in_array( $text, $roles ) && $domain !== $plugin_domain ) {
1039 - return translate_with_gettext_context( $text, $context, $plugin_domain );
1040 - }
1041 -
1042 - return $translations;
1043 -}
1044 -
1045 -add_filter( 'gettext_with_context', '_learn_press_translate_user_roles', 10, 4 );
1046 -
1047 -if ( ! function_exists( 'learn_press_send_json' ) ) {
1048 - function learn_press_send_json( $data ) {
1049 - echo '<-- LP_AJAX_START -->';
1050 - echo wp_json_encode( $data );
1051 - echo '<-- LP_AJAX_END -->';
1052 - die;
1053 - }
1054 -}
1055 -
1056 -/**
1057 - * Send json with success signal to browser.
1058 - *
1059 - * @param array|object|WP_Error $data
1060 - *
1061 - * @since 3.0.1
1062 - */
1063 -function learn_press_send_json_error( $data = '' ) {
1064 - $response = array( 'success' => false );
1065 -
1066 - if ( isset( $data ) ) {
1067 - if ( is_wp_error( $data ) ) {
1068 - $result = array();
1069 - foreach ( $data->errors as $code => $messages ) {
1070 - foreach ( $messages as $message ) {
1071 - $result[] = array(
1072 - 'code' => $code,
1073 - 'message' => $message,
1074 - );
1075 - }
1076 - }
1077 -
1078 - $response['data'] = $result;
1079 - } else {
1080 - $response['data'] = $data;
1081 - }
1082 - }
1083 -
1084 - learn_press_send_json( $response );
1085 -}
1086 -
1087 -/**
1088 - * Send json with error signal to browser.
1089 - *
1090 - * @param array|object|WP_Error $data
1091 - *
1092 - * @since 3.0.0
1093 - */
1094 -function learn_press_send_json_success( $data = '' ) {
1095 - $response = array( 'success' => true );
1096 -
1097 - if ( isset( $data ) ) {
1098 - $response['data'] = $data;
1099 - }
1100 -
1101 - learn_press_send_json( $response );
1102 -}
1103 -
1104 -/**
1105 - * Check if ajax is calling then send json data.
1106 - *
1107 - * @param array $data
1108 - * @param mixed $callback
1109 - *
1110 - * @return bool
1111 - */
1112 -function learn_press_maybe_send_json( $data, $callback = null ) {
1113 - if ( learn_press_is_ajax() ) {
1114 - is_callable( $callback ) && call_user_func( $callback );
1115 - $message = learn_press_get_messages( true );
1116 - if ( empty( $data['message'] ) && $message ) {
1117 - $data['message'] = $message;
1118 - }
1119 - learn_press_send_json( $data );
1120 - }
1121 -
1122 - return false;
1123 -}
1124 -
1125 -/**
1126 - * Get data from request.
1127 - *
1128 - * @param string $key
1129 - * @param mixed $default
1130 - * @param mixed $hash
1131 - *
1132 - * @return mixed
1133 - */
1134 -function learn_press_get_request( $key, $default = null, $hash = null ) {
1135 - $return = $default;
1136 -
1137 - if ( $hash ) {
1138 - if ( ! empty( $hash[ $key ] ) ) {
1139 - $return = $hash[ $key ];
1140 - }
1141 - } else {
1142 - if ( ! empty( $_POST[ $key ] ) ) {
1143 - $return = LP_Helper::sanitize_params_submitted( $_POST[ $key ] );
1144 - } elseif ( ! empty( $_GET[ $key ] ) ) {
1145 - $return = LP_Helper::sanitize_params_submitted( $_GET[ $key ] );
1146 - } elseif ( ! empty( $_REQUEST[ $key ] ) ) {
1147 - $return = LP_Helper::sanitize_params_submitted( $_REQUEST[ $key ] );
1148 - }
1149 - }
1150 -
1151 - return $return;
1152 -}
1153 -
1154 -/**
1155 - * @return mixed
1156 - */
1157 -function is_learnpress() {
1158 - return apply_filters(
1159 - 'is_learnpress',
1160 - ( learn_press_is_course_archive() || learn_press_is_course_taxonomy() || learn_press_is_course() || learn_press_is_quiz() || learn_press_is_search() ) ? true : false
1161 - );
1162 -}
1163 -
1164 -if ( ! function_exists( 'learn_press_is_search' ) ) {
1165 - function learn_press_is_search() {
1166 - return array_key_exists( 's', $_REQUEST ) && array_key_exists( 'ref', $_REQUEST ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course';
1167 - }
1168 -}
1169 -
1170 -if ( ! function_exists( 'learn_press_is_courses' ) ) {
1171 - function learn_press_is_courses() {
1172 - return learn_press_is_course_archive();
1173 - }
1174 -}
1175 -
1176 -
1177 -if ( ! function_exists( 'learn_press_is_course_archive' ) ) {
1178 - function learn_press_is_course_archive() {
1179 - global $wp_query;
1180 -
1181 - $queried_object_id = ! empty( $wp_query->queried_object ) ? $wp_query->queried_object : 0;
1182 - $is_tag = defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG || is_tax( 'course_tag' );
1183 - $is_category = defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY || is_tax( 'course_category' );
1184 - $page_id = learn_press_get_page_id( 'courses' );
1185 -
1186 - return ( $is_category || $is_tag ) || is_post_type_archive( 'lp_course' ) || ( $page_id && ( $queried_object_id && is_page( $page_id ) ) );
1187 - }
1188 -}
1189 -
1190 -if ( ! function_exists( 'learn_press_is_course_tax' ) ) {
1191 - function learn_press_is_course_tax() {
1192 - return is_tax( get_object_taxonomies( LP_COURSE_CPT ) );
1193 - }
1194 -}
1195 -
1196 -if ( ! function_exists( 'learn_press_is_course_taxonomy' ) ) {
1197 - function learn_press_is_course_taxonomy() {
1198 - return ( defined( 'LEARNPRESS_IS_TAX' ) && LEARNPRESS_IS_TAX ) || learn_press_is_course_tax();
1199 - }
1200 -}
1201 -
1202 -
1203 -if ( ! function_exists( 'learn_press_is_course_category' ) ) {
1204 - function learn_press_is_course_category( $term = '' ) {
1205 - return ( defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY ) || is_tax( 'course_category', $term );
1206 - }
1207 -}
1208 -
1209 -
1210 -if ( ! function_exists( 'learn_press_is_course_tag' ) ) {
1211 - function learn_press_is_course_tag( $term = '' ) {
1212 - return ( defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG ) || is_tax( 'course_tag', $term );
1213 - }
1214 -}
1215 -
1216 -if ( ! function_exists( 'learn_press_is_course' ) ) {
1217 - function learn_press_is_course(): bool {
1218 - try {
1219 - return is_singular( array( LP_COURSE_CPT ) );
1220 - } catch ( Throwable $e ) {
1221 - }
1222 -
1223 - return false;
1224 - }
1225 -}
1226 -
1227 -if ( ! function_exists( 'learn_press_is_lesson' ) ) {
1228 - function learn_press_is_lesson() {
1229 - return is_singular( array( LP_LESSON_CPT ) );
1230 - }
1231 -}
1232 -
1233 -if ( ! function_exists( 'learn_press_is_quiz' ) ) {
1234 - function learn_press_is_quiz() {
1235 - return is_singular( array( LP_QUIZ_CPT ) );
1236 - }
1237 -}
1238 -
1239 -function lp_content_has_shortcode( $tag = '' ) {
1240 - global $post;
1241 -
1242 - return is_singular() && is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, $tag );
1243 -}
1244 -
1245 -/**
1246 - * Returns true when viewing profile page.
1247 - *
1248 - * @return bool
1249 - */
1250 -function learn_press_is_profile() {
1251 - $page_id = learn_press_get_page_id( 'profile' );
1252 -
1253 - if ( $page_id && is_page( $page_id ) || lp_content_has_shortcode( 'learn_press_profile' ) ) {
1254 - return true;
1255 - }
1256 -
1257 - return apply_filters( 'learn-press/is-profile', false );
1258 -}
1259 -
1260 -/**
1261 - * Return true if user is in checking out page
1262 - *
1263 - * @return bool
1264 - */
1265 -function learn_press_is_checkout() {
1266 - $page_id = learn_press_get_page_id( 'checkout' );
1267 -
1268 - if ( $page_id && is_page( $page_id ) ) {
1269 - return true;
1270 - }
1271 -
1272 - return apply_filters( 'learn-press/is-checkout', false );
1273 -}
1274 -
1275 -function learn_press_is_instructors() {
1276 - $page_id = learn_press_get_page_id( 'instructors' );
1277 -
1278 - if ( $page_id && is_page( $page_id ) ) {
1279 - return true;
1280 - }
1281 -
1282 - return apply_filters( 'learn-press/is-instructor', false );
1283 -}
1284 -
1285 -
1286 -/**
1287 - * Return register permalink
1288 - *
1289 - * @return mixed
1290 - */
1291 -function learn_press_get_register_url() {
1292 - return apply_filters( 'learn_press_register_url', wp_registration_url() );
1293 -}
1294 -
1295 -/**
1296 - * Add a new notice into queue
1297 - *
1298 - * @param string
1299 - * @param string
1300 - *
1301 - * @return mixed
1302 - * @deprecated 4.2.5
1303 - */
1304 -function learn_press_add_notice( $message, $type = 'updated' ) {
1305 - _deprecated_function( __FUNCTION__, '4.2.5' );
1306 - LP_Admin_Notice::instance()->add( $message, $type );
1307 -}
1308 -
1309 -/**
1310 - * Set user's cookie
1311 - *
1312 - * @param string $name
1313 - * @param mixed $value
1314 - * @param int $expire
1315 - * @param bool $httponly
1316 - *
1317 - * @editor tungnx
1318 - * @version 1.0.3
1319 - */
1320 -function learn_press_setcookie( string $name = '', string $value = '', int $expire = 0, bool $httponly = true ) {
1321 - @setcookie( $name, $value, $expire, COOKIEPATH ?: '/', COOKIE_DOMAIN, is_ssl(), $httponly );
1322 -}
1323 -
1324 -/**
1325 - * Clear cookie
1326 - *
1327 - * @param string $name
1328 - */
1329 -function learn_press_remove_cookie( string $name = '' ) {
1330 - if ( ! empty( $name ) ) {
1331 - setcookie( $name, '', time() - YEAR_IN_SECONDS, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, is_ssl(), true );
1332 - }
1333 -
1334 - if ( array_key_exists( $name, $_COOKIE ) ) {
1335 - unset( $_COOKIE[ $name ] );
1336 - }
1337 -}
1338 -
1339 -/**
1340 - * Filter the login url so third-party can be customized
1341 - *
1342 - * @param string $redirect
1343 - *
1344 - * @return mixed
1345 - */
1346 -function learn_press_get_login_url( $redirect = null ) {
1347 - $url = wp_login_url( $redirect );
1348 - $profile_page = learn_press_get_page_link( 'profile' );
1349 -
1350 - if ( 'yes' === LP_Settings::instance()->get( 'enable_login_profile' ) && $profile_page ) {
1351 - $parse_url = parse_url( $url );
1352 - $url = $profile_page . ( ! empty( $parse_url['query'] ) ? '?' . $parse_url['query'] : '' );
1353 - }
1354 -
1355 - return apply_filters( 'learn-press/login-url', $url );
1356 -}
1357 -
1358 -/**
1359 - * Add variable to an url by checking the permalink structure.
1360 - *
1361 - * @param string $name
1362 - * @param string $value
1363 - * @param string $url
1364 - *
1365 - * @return string
1366 - */
1367 -function learn_press_get_endpoint_url( $name, $value, $url ) {
1368 - if ( ! $url ) {
1369 - $url = get_permalink();
1370 - }
1371 -
1372 - // Map endpoint to options
1373 - $name = isset( LearnPress::instance()->query_vars[ $name ] ) ? LearnPress::instance()->query_vars[ $name ] : $name;
1374 -
1375 - if ( get_option( 'permalink_structure' ) ) {
1376 - if ( strstr( $url, '?' ) ) {
1377 - $query_string = '?' . parse_url( $url, PHP_URL_QUERY );
1378 - $url = current( explode( '?', $url ) );
1379 - } else {
1380 - $query_string = '';
1381 - }
1382 - $url = trailingslashit( $url ) . ( $name ? $name . '/' : '' ) . $value . $query_string;
1383 -
1384 - } else {
1385 - $url = esc_url_raw( add_query_arg( $name, $value, $url ) );
1386 - }
1387 -
1388 - return apply_filters( 'learn_press_get_endpoint_url', esc_url_raw( $url ), $name, $value, $url );
1389 -}
1390 -
1391 -/**
1392 - * @deprecated 4.2.3
1393 - */
1394 -function learn_press_is_yes( $value ) {
1395 - _deprecated_function( __FUNCTION__, '4.2.3' );
1396 - return ( $value === 1 ) || ( $value === '1' ) || ( $value == 'yes' ) || ( $value == true ) || ( $value == 'on' );
1397 -}
1398 -
1399 -/**
1400 - * @param mixed $value
1401 - *
1402 - * @return bool
1403 - * @deprecated 4.2.3
1404 - */
1405 -function _is_false_value( $value ) {
1406 - _deprecated_function( __FUNCTION__, '4.2.3' );
1407 - if ( is_numeric( $value ) ) {
1408 - return $value == 0;
1409 - } elseif ( is_string( $value ) ) {
1410 - return ( empty( $value ) || is_null( $value ) || in_array( $value, array( 'no', 'off', 'false' ) ) );
1411 - }
1412 -
1413 - return ! ! $value;
1414 -}
1415 -
1416 -/**
1417 - * Map the query vars from LP to query vars of WP core
1418 - * when WP parse the requesting.
1419 - */
1420 -function learn_press_parse_request() {
1421 - global $wp;
1422 -
1423 - // Map query vars to their keys, or get them if endpoints are not supported
1424 - foreach ( LearnPress::instance()->query_vars as $key => $var ) {
1425 - if ( isset( $_GET[ $var ] ) ) {
1426 - $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $_GET[ $var ] ?? '' );
1427 - } elseif ( isset( $wp->query_vars[ $var ] ) ) {
1428 - $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $wp->query_vars[ $var ] ?? '' );
1429 - }
1430 - }
1431 -}
1432 -
1433 -add_action( 'parse_request', 'learn_press_parse_request' );
1434 -
1435 -if ( ! function_exists( 'learn_press_reset_auto_increment' ) ) {
1436 - /**
1437 - * Reset AUTO INCREMENT of the table.
1438 - *
1439 - * @param $table
1440 - */
1441 - function learn_press_reset_auto_increment( $table ) {
1442 - global $wpdb;
1443 - $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}$table AUTO_INCREMENT = %d", 1 ) );
1444 - }
1445 -}
1446 -
1447 -/**
1448 - * Get the cart object in checkout page
1449 - *
1450 - * @return LP_Cart
1451 - * @deprecated 4.2.0
1452 - */
1453 -function learn_press_get_checkout_cart() {
1454 - _deprecated_function( __FUNCTION__, '4.2.0', 'LearnPress::instance()->cart' );
1455 - return apply_filters( 'learn_press_checkout_cart', LearnPress::instance()->cart );
1456 -}
1457 -
1458 -function learn_press_user_time( $time, $format = 'timestamp' ) {
1459 - if ( is_string( $time ) ) {
1460 - $time = @strtotime( $time );
1461 - }
1462 - $time = $time + ( get_option( 'gmt_offset' ) - $_COOKIE['timezone'] / 60 ) * HOUR_IN_SECONDS;
1463 - switch ( $format ) {
1464 - case 'timestamp':
1465 - return $time;
1466 - default:
1467 - return date( 'Y-m-d H:i:s', $time );
1468 - }
1469 -}
1470 -
1471 -function learn_press_get_current_version() {
1472 - $data = get_plugin_data( LP_PLUGIN_FILE, $markup = true, $translate = true );
1473 -
1474 - return $data['Version'];
1475 -}
1476 -
1477 -/**
1478 - * Get current tab is displaying in user profile.
1479 - * If there is no tab then get the first tab in
1480 - * the list of tabs.
1481 - *
1482 - * @param bool $default
1483 - *
1484 - * @return mixed|string
1485 - * @deprecated 4.2.2
1486 - * addon commission 4.0.2 still use this function
1487 - */
1488 -function learn_press_get_current_profile_tab( $default = true ) {
1489 - global $wp_query, $wp;
1490 - $current = '';
1491 -
1492 - // Only load on profile page.
1493 - if ( ! LP_Page_Controller::is_page_profile() ) {
1494 - return false;
1495 - }
1496 -
1497 - if ( ! empty( $_REQUEST['tab'] ) ) {
1498 - $current = LP_Helper::sanitize_params_submitted( $_REQUEST['tab'] );
1499 - } elseif ( ! empty( $wp_query->query_vars['tab'] ) ) {
1500 - $current = $wp_query->query_vars['tab'];
1501 - } elseif ( ! empty( $wp->query_vars['view'] ) ) {
1502 - $current = $wp->query_vars['view'];
1503 - } else {
1504 - $tabs = learn_press_get_user_profile_tabs();
1505 - if ( $default && $tabs ) {
1506 - // Fixed for array_keys does not work with ArrayAccess instance
1507 - if ( $tabs instanceof LP_Profile_Tabs ) {
1508 - $tabs = $tabs->tabs();
1509 - }
1510 -
1511 - $tab_keys = array_keys( $tabs );
1512 - $current = reset( $tab_keys );
1513 - }
1514 - }
1515 -
1516 - return $current;
1517 -}
1518 -
1519 -//add_action( 'init', 'learn_press_get_current_profile_tab' );
1520 -
1521 -function learn_press_profile_tab_exists( $tab ) {
1522 - $tabs = learn_press_get_user_profile_tabs();
1523 -
1524 - if ( $tabs ) {
1525 - return ! empty( $tabs[ $tab ] ) ? true : false;
1526 - }
1527 -
1528 - return false;
1529 -}
1530 -
1531 -function learn_press_single_term_title( $prefix = '', $display = true ) {
1532 - $term = get_queried_object();
1533 -
1534 - if ( ! $term ) {
1535 - return '';
1536 - }
1537 -
1538 - if ( learn_press_is_course_category() ) {
1539 - $term_name = apply_filters( 'single_course_category_title', $term->name );
1540 - } elseif ( learn_press_is_course_tag() ) {
1541 - $term_name = apply_filters( 'single_course_tag_title', $term->name );
1542 - } elseif ( learn_press_is_course_taxonomy() ) {
1543 - $term_name = apply_filters( 'single_course_term_title', $term->name );
1544 - } else {
1545 - return single_term_title( $prefix, $display );
1546 - }
1547 -
1548 - if ( empty( $term_name ) ) {
1549 - return single_term_title( $prefix, $display );
1550 - }
1551 -
1552 - if ( $display ) {
1553 - echo wp_kses_post( $prefix . $term_name );
1554 - }
1555 -
1556 - return $prefix . $term_name;
1557 -}
1558 -
1559 -/**
1560 - * Control the template file if user is searching course.
1561 - * Use the template of archive course to display the
1562 - * result if there is a flag in request to search course.
1563 - *
1564 - * @param string $template
1565 - *
1566 - * @return string
1567 - */
1568 -function learn_press_search_template( $template ) {
1569 - if ( ! empty( $_REQUEST['ref'] ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course' ) {
1570 - $template = learn_press_locate_template( 'archive-course.php' );
1571 - }
1572 -
1573 - return $template;
1574 -}
1575 -
1576 -/**
1577 - * Auto enroll user to a course after an order is completed
1578 - * if the option auto-enroll is turn on.
1579 - *
1580 - * @param int $order_id
1581 - *
1582 - * @return mixed
1583 - * @editor tungnx
1584 - */
1585 -function learn_press_auto_enroll_user_to_courses( $order_id ) {
1586 - _deprecated_function( __FUNCTION__, '4.1.3' );
1587 -}
1588 -
1589 -// add_action( 'learn_press_order_status_completed', 'learn_press_auto_enroll_user_to_courses' );
1590 -
1591 -/**
1592 - * Return true if enable cart
1593 - *
1594 - * @return bool
1595 - */
1596 -function learn_press_is_enable_cart() {
1597 - return defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART == true;
1598 -}
1599 -
1600 -/**
1601 - * Short way to get checkout object
1602 - *
1603 - * @param array
1604 - *
1605 - * @return LP_Checkout
1606 - */
1607 -function learn_press_get_checkout( $args = null ) {
1608 - $checkout = LP_Checkout::instance();
1609 -
1610 - if ( is_array( $args ) ) {
1611 - foreach ( $args as $k => $v ) {
1612 - $checkout->{$k} = $v;
1613 - }
1614 - }
1615 -
1616 - return $checkout;
1617 -}
1618 -
1619 -if ( defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART ) {
1620 - add_filter( 'learn_press_checkout_settings', '_learn_press_cart_settings', 10, 2 );
1621 - function _learn_press_cart_settings( $settings, $class ) {
1622 - $settings = array_merge(
1623 - $settings,
1624 - array(
1625 - array(
1626 - 'title' => __( 'Cart', 'learnpress' ),
1627 - 'type' => 'title',
1628 - ),
1629 - array(
1630 - 'title' => __( 'Enable cart', 'learnpress' ),
1631 - 'desc' => __(
1632 - 'Check this option to enable users to purchase multiple courses at one time.',
1633 - 'learnpress'
1634 - ),
1635 - 'id' => $class->get_field_name( 'enable_cart' ),
1636 - 'default' => 'yes',
1637 - 'type' => 'checkbox',
1638 - ),
1639 - array(
1640 - 'title' => __( 'Add to cart redirect', 'learnpress' ),
1641 - 'desc' => __( 'Redirect to checkout immediately after adding the course to the cart.', 'learnpress' ),
1642 - 'id' => $class->get_field_name( 'redirect_after_add' ),
1643 - 'default' => 'yes',
1644 - 'type' => 'checkbox',
1645 - ),
1646 - array(
1647 - 'title' => __( 'AJAX add to cart', 'learnpress' ),
1648 - 'desc' => __( 'Using AJAX to add the course to the cart.', 'learnpress' ),
1649 - 'id' => $class->get_field_name( 'ajax_add_to_cart' ),
1650 - 'default' => 'no',
1651 - 'type' => 'checkbox',
1652 - ),
1653 - array(
1654 - 'title' => __( 'Cart page', 'learnpress' ),
1655 - 'id' => $class->get_field_name( 'cart_page_id' ),
1656 - 'default' => '',
1657 - 'type' => 'pages-dropdown',
1658 - ),
1659 - )
1660 - );
1661 -
1662 - return $settings;
1663 - }
1664 -} else {
1665 - add_filter( 'learn_press_enable_cart', '_learn_press_enable_cart', 1000 );
1666 - function _learn_press_enable_cart( $r ) {
1667 - return false;
1668 - }
1669 -
1670 - add_filter( 'learn_press_get_template', '_learn_press_enroll_button', 1000, 5 );
1671 - function _learn_press_enroll_button( $located, $template_name, $args, $template_path, $default_path ) {
1672 - if ( $template_name == 'single-course/enroll-button.php' ) {
1673 - $located = learn_press_locate_template(
1674 - 'single-course/enroll-button-new.php',
1675 - $template_path,
1676 - $default_path
1677 - );
1678 - }
1679 -
1680 - return $located;
1681 - }
1682 -}
1683 -
1684 -/**
1685 - * Returns checkout url from setting
1686 - *
1687 - * @return string
1688 - */
1689 -function learn_press_get_checkout_url() {
1690 - $checkout_url = learn_press_get_page_link( 'checkout' );
1691 -
1692 - return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
1693 -}
1694 -
1695 -/**
1696 - * @return string
1697 - */
1698 -function learn_press_checkout_needs_payment() {
1699 - return LearnPress::instance()->cart->needs_payment();
1700 -}
1701 -
1702 -/**
1703 - * Return plugin basename
1704 - *
1705 - * @param string $filepath
1706 - *
1707 - * @return string
1708 - */
1709 -/*
1710 -function learn_press_plugin_basename( $filepath ) {
1711 - $file = str_replace( '\\', '/', $filepath );
1712 - $file = preg_replace( '|/+|', '/', $file );
1713 - $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR );
1714 - $plugin_dir = preg_replace( '|/+|', '/', $plugin_dir );
1715 - $mu_plugin_dir = str_replace( '\\', '/', WPMU_PLUGIN_DIR );
1716 - $mu_plugin_dir = preg_replace( '|/+|', '/', $mu_plugin_dir );
1717 - $sp_plugin_dir = dirname( $filepath );
1718 - $sp_plugin_dir = dirname( $sp_plugin_dir );
1719 - $sp_plugin_dir = str_replace( '\\', '/', $sp_plugin_dir );
1720 - $sp_plugin_dir = preg_replace( '|/+|', '/', $sp_plugin_dir );
1721 -
1722 - $file = preg_replace(
1723 - '#^' . preg_quote( $sp_plugin_dir, '#' ) . '/|^' . preg_quote(
1724 - $plugin_dir,
1725 - '#'
1726 - ) . '/|^' . preg_quote(
1727 - $mu_plugin_dir,
1728 - '#'
1729 - ) . '/#',
1730 - '',
1731 - $file
1732 - );
1733 - $file = trim( $file, '/' );
1734 -
1735 - return strtolower( $file );
1736 -}*/
1737 -
1738 -/**
1739 - * Update log data for each LP version into wp option.
1740 - *
1741 - * @param string $version
1742 - * @param mixed $data
1743 - */
1744 -function learn_press_update_log( $version, $data ) {
1745 - $logs = get_option( 'learn_press_update_logs' );
1746 - if ( ! $logs ) {
1747 - $logs = array( $version => $data );
1748 - } else {
1749 - $logs[ $version ] = $data;
1750 - }
1751 - update_option( 'learn_press_update_logs', $logs );
1752 -}
1753 -
1754 -/**
1755 - * Output variables to screen for debugging.
1756 - */
1757 -function learn_press_debug() {
1758 - $args = func_get_args();
1759 - $debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
1760 -
1761 - echo '<pre>';
1762 - print_r( $debug );
1763 - $arg = false;
1764 -
1765 - if ( $args ) {
1766 - foreach ( $args as $arg ) {
1767 - echo "\n======LearnPress Debug=======\n";
1768 - print_r( $arg );
1769 - echo "\n=============================\n";
1770 - }
1771 - }
1772 - echo '</pre>';
1773 -
1774 - if ( true === $arg ) {
1775 - die( __FUNCTION__ );
1776 - }
1777 -}
1778 -
1779 -function learn_press_get_requested_post_type() {
1780 - global $pagenow;
1781 - if ( $pagenow == 'post-new.php' && ! empty( $_REQUEST['post_type'] ) ) {
1782 - $post_type = LP_Helper::sanitize_params_submitted( $_REQUEST['post_type'] );
1783 - } else {
1784 - $post_id = learn_press_get_post();
1785 - $post_type = learn_press_get_post_type( $post_id );
1786 - }
1787 -
1788 - return $post_type;
1789 -}
1790 -
1791 -/**
1792 - * Get human string from grade slug.
1793 - *
1794 - * @param string $slug
1795 - *
1796 - * @return string
1797 - */
1798 -function learn_press_get_graduation_text( $slug ) {
1799 - switch ( $slug ) {
1800 - case 'passed':
1801 - $text = esc_html__( 'Passed', 'learnpress' );
1802 - break;
1803 - case 'failed':
1804 - $text = esc_html__( 'Failed', 'learnpress' );
1805 - break;
1806 - case 'in-progress':
1807 - $text = esc_html__( 'In Progress', 'learnpress' );
1808 - break;
1809 - default:
1810 - $text = $slug;
1811 - }
1812 -
1813 - return apply_filters( 'learn-press/get-graduation-text', $text, $slug );
1814 -}
1815 -
1816 -if ( ! function_exists( 'learn_press_is_negative_value' ) ) {
1817 - function learn_press_is_negative_value( $value ) {
1818 - $return = in_array( $value, array( 'no', 'off', 'false', '0' ) ) || ! $value || $value == '' || $value == null;
1819 -
1820 - return $return;
1821 - }
1822 -}
1823 -
1824 -/**
1825 - * Filter to comment reply link to fix bug the link is invalid for
1826 - * lesson or quiz.
1827 - *
1828 - * @param string $link
1829 - * @param array $args
1830 - * @param WP_Comment $comment
1831 - * @param WP_Post $post
1832 - *
1833 - * @return string
1834 - */
1835 -function learn_press_comment_reply_link( $link, $args = array(), $comment = null, $post = null ) {
1836 -
1837 - $post_type = learn_press_get_post_type( $post );
1838 -
1839 - if ( ! learn_press_is_support_course_item_type( $post_type ) ) {
1840 - return $link;
1841 - }
1842 -
1843 - $course_item = LP_Global::course_item();
1844 -
1845 - if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
1846 - $link = sprintf(
1847 - '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
1848 - esc_url_raw( wp_login_url( get_permalink() ) ),
1849 - $args['login_text']
1850 - );
1851 - } elseif ( $course_item ) {
1852 - $onclick = sprintf(
1853 - 'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
1854 - $args['add_below'],
1855 - $comment->comment_ID,
1856 - $args['respond_id'],
1857 - $post->ID
1858 - );
1859 -
1860 - $link = sprintf(
1861 - "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
1862 - esc_url_raw(
1863 - add_query_arg(
1864 - array(
1865 - 'replytocom' => $comment->comment_ID,
1866 - ),
1867 - $course_item->get_permalink()
1868 - )
1869 - ) . '#' . $args['respond_id'],
1870 - $onclick,
1871 - esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
1872 - $args['reply_text']
1873 - );
1874 - }
1875 -
1876 - return $link;
1877 -}
1878 -
1879 -add_filter( 'comment_reply_link', 'learn_press_comment_reply_link', 10, 4 );
1880 -
1881 -/**
1882 - * Sanitize content of tooltip
1883 - *
1884 - * @param string $tooltip
1885 - * @param bool $html
1886 - *
1887 - * @return string
1888 - */
1889 -function learn_press_sanitize_tooltip( $tooltip, $html = false ) {
1890 - if ( $html ) {
1891 - $tooltip = htmlspecialchars(
1892 - wp_kses(
1893 - html_entity_decode( $tooltip ),
1894 - array(
1895 - 'br' => array(),
1896 - 'em' => array(),
1897 - 'strong' => array(),
1898 - 'small' => array(),
1899 - 'span' => array(),
1900 - 'ul' => array(),
1901 - 'li' => array(),
1902 - 'ol' => array(),
1903 - 'p' => array(),
1904 - )
1905 - )
1906 - );
1907 - } else {
1908 - $tooltip = esc_attr( $tooltip );
1909 - }
1910 -
1911 - return $tooltip;
1912 -}
1913 -
1914 -function learn_press_tooltip( $tooltip, $html = false ) {
1915 - $tooltip = learn_press_sanitize_tooltip( $tooltip, $html );
1916 - echo '<span class="learn-press-tooltip" data-tooltip="' . esc_attr( $tooltip ) . '"></span>';
1917 -}
1918 -
1919 -/**
1920 - * Get default static pages of LP.
1921 - *
1922 - * @return array
1923 - *
1924 - * @since 3.0.0
1925 - * @deprecated 4.2.3
1926 - */
1927 -function learn_press_static_page_ids() {
1928 - $pages = LP_Object_Cache::get( 'static-page-ids', 'learn-press' );
1929 -
1930 - if ( false === $pages ) {
1931 - $pages = array(
1932 - 'checkout' => learn_press_get_page_id( 'checkout' ),
1933 - 'courses' => learn_press_get_page_id( 'courses' ),
1934 - 'profile' => learn_press_get_page_id( 'profile' ),
1935 - 'become_a_teacher' => learn_press_get_page_id( 'become_a_teacher' ),
1936 - );
1937 -
1938 - foreach ( $pages as $name => $id ) {
1939 - if ( ! get_post( $id ) ) {
1940 - $pages[ $name ] = 0;
1941 - }
1942 - }
1943 -
1944 - LP_Object_Cache::set( 'static-page-ids', $pages, 'learn-press' );
1945 - }
1946 -
1947 - return apply_filters( 'learn-press/static-page-ids', $pages );
1948 -}
1949 -
1950 -/**
1951 - * Callback function for sorting to array|object by key|prop priority.
1952 - *
1953 - * @param array|object $a
1954 - * @param array|object $b
1955 - *
1956 - * @return int
1957 - * @since 3.0.0
1958 - */
1959 -function learn_press_sort_list_by_priority_callback( $a, $b ) {
1960 - $a_priority = null;
1961 - $b_priority = null;
1962 -
1963 - if ( is_array( $a ) && array_key_exists( 'priority', $a ) ) {
1964 - $a_priority = $a['priority'];
1965 - } elseif ( is_object( $a ) ) {
1966 - if ( is_callable( array( $a, 'get_priority' ) ) ) {
1967 - $a_priority = $a->get_priority();
1968 - } elseif ( property_exists( $a, 'priority' ) ) {
1969 - $a_priority = $a->priority;
1970 - }
1971 - }
1972 -
1973 - if ( is_array( $b ) && array_key_exists( 'priority', $b ) ) {
1974 - $b_priority = $b['priority'];
1975 - } elseif ( is_object( $b ) ) {
1976 - if ( is_callable( array( $b, 'get_priority' ) ) ) {
1977 - $b_priority = $b->get_priority();
1978 - } elseif ( property_exists( $b, 'priority' ) ) {
1979 - $b_priority = $b->priority;
1980 - }
1981 - }
1982 -
1983 - if ( $a_priority === $b_priority ) {
1984 - return 0;
1985 - }
1986 -
1987 - return ( $a_priority < $b_priority ) ? - 1 : 1;
1988 -}
1989 -
1990 -/**
1991 - * Localize date with custom format.
1992 - *
1993 - * @param int|bool $timestamp
1994 - * @param string $format
1995 - * @param bool $gmt
1996 - *
1997 - * @return string
1998 - * @since 3.0.0
1999 - * @deprcated 4.2.6 use LP_Datetime format instead
2000 - */
2001 -function learn_press_date_i18n( $timestamp = 0, string $format = '', bool $gmt = false ): string {
2002 - if ( ! $format ) {
2003 - $format = get_option( 'date_format' );
2004 - }
2005 -
2006 - $date_str = date_i18n( $format, $timestamp, $gmt );
2007 - if ( ! is_string( $date_str ) ) {
2008 - $date_str = '';
2009 - }
2010 -
2011 - return $date_str;
2012 -}
2013 -
2014 -/**
2015 - * Get item types of course support for blocking. Default is lp_lesson
2016 - *
2017 - * @return array
2018 - * @since 3.0.0
2019 - */
2020 -function learn_press_get_block_course_item_types() {
2021 - return apply_filters( 'learn-press/block-course-item-types', array( LP_LESSON_CPT, LP_QUIZ_CPT ) );
2022 -}
2023 -
2024 -/**
2025 - * Get post type of a post from cache.
2026 - * If there is no data stored in cache then
2027 - * get it from WP API.
2028 - *
2029 - * @param int|WP_Post $post
2030 - *
2031 - * @return string
2032 - * @since 3.1.0
2033 - */
2034 -function learn_press_get_post_type( $post ) {
2035 - $post_types = LP_Object_Cache::get( 'post-types', 'learn-press' );
2036 -
2037 - if ( false === $post_types ) {
2038 - $post_types = array();
2039 - }
2040 -
2041 - if ( is_object( $post ) ) {
2042 - $post_id = $post->ID;
2043 - } else {
2044 - $post_id = absint( $post );
2045 - }
2046 -
2047 - if ( empty( $post_types[ $post_id ] ) ) {
2048 - $post_type = get_post_type( $post_id );
2049 - $post_types[ $post_id ] = $post_type;
2050 - LP_Object_Cache::set( 'post-types', $post_types, 'learn-press' );
2051 - } else {
2052 - $post_type = $post_types[ $post_id ];
2053 - }
2054 -
2055 - return $post_type;
2056 -}
2057 -
2058 -/**
2059 - * Update option to enable shuffle themes for ad.
2060 - *
2061 - * @since 3.2.1
2062 - */
2063 -function _learn_press_schedule_enable_shuffle_themes() {
2064 - update_option( 'learn_press_ad_shuffle_themes', 'yes' );
2065 -}
2066 -
2067 -add_action( 'learn-press/schedule-enable-shuffle-themes', '_learn_press_schedule_enable_shuffle_themes' );
2068 -
2069 -/**
2070 - * Return localize script data for admin.
2071 - *
2072 - * @return array
2073 - * @since 3.2.6
2074 - * @version 1.0.1
2075 - */
2076 -function learn_press_global_script_params(): array {
2077 - $localize = [
2078 - 'ajax' => admin_url( 'admin-ajax.php' ),
2079 - 'plugin_url' => LearnPress::instance()->plugin_url(),
2080 - 'siteurl' => home_url(),
2081 - //'current_url' => learn_press_get_current_url(),
2082 - 'theme' => get_stylesheet(),
2083 - 'localize' => array(
2084 - 'button_ok' => __( 'OK', 'learnpress' ),
2085 - 'button_cancel' => __( 'Cancel', 'learnpress' ),
2086 - 'button_yes' => __( 'Yes', 'learnpress' ),
2087 - 'button_no' => __( 'No', 'learnpress' ),
2088 - ),
2089 - 'rest' => esc_url_raw( rest_url() ),
2090 - 'nonce' => wp_create_nonce( 'wp_rest' ),
2091 - 'is_admin' => current_user_can( ADMIN_ROLE ),
2092 - ];
2093 -
2094 - return apply_filters( 'lp/admin/localize/scripts', $localize );
2095 -}
2096 -
2097 -/**
2098 - * Return list types of questions that support answer options.
2099 - *
2100 - * @return array
2101 - * @since 3.3.0
2102 - */
2103 -function learn_press_get_question_support_answer_options() {
2104 - $questions = learn_press_get_question_support_feature( 'answer-options' );
2105 -
2106 - return apply_filters( 'learn-press/questions-support-answer-options', $questions );
2107 -}
2108 -
2109 -/**
2110 - * Return list types of question that support a feature.
2111 - *
2112 - * @param string $feature
2113 - *
2114 - * @return array
2115 - * @since 3.3.0
2116 - */
2117 -function learn_press_get_question_support_feature( $feature ) {
2118 - $questions = array();
2119 - $types = LP_Global::get_object_supports( 'question' );
2120 -
2121 - if ( $types ) {
2122 - foreach ( $types as $type => $features ) {
2123 - if ( array_key_exists( $feature, $features ) ) {
2124 - $questions[] = $type;
2125 - }
2126 - }
2127 - }
2128 -
2129 - return $questions;
2130 -}
2131 -
2132 -/**
2133 - * LP Cookie
2134 - *
2135 - * @param $name
2136 - * @param $namespace
2137 - *
2138 - * @return mixed|null
2139 - */
2140 -function learn_press_cookie_get( $name, $namespace = 'LP' ) {
2141 - if ( $namespace ) {
2142 - $cookie = ! empty( $_COOKIE[ $namespace ] ) ? (array) json_decode( LP_Helper::sanitize_params_submitted( stripslashes( $_COOKIE[ $namespace ] ), 'html' ) ) : array();
2143 - } else {
2144 - $cookie = $_COOKIE;
2145 - }
2146 -
2147 - return $cookie[ $name ] ?? null;
2148 -}
2149 -
2150 -/**
2151 - * Get default methods to evaluate course results.
2152 - *
2153 - * @param string $return - Optional. 'keys' will return keys instead of all.
2154 - *
2155 - * @return array
2156 - * @since 3.x.x
2157 - */
2158 -function learn_press_course_evaluation_methods( $postid, $return = '', $final_quizz_passing = '' ) {
2159 - $final_quiz_btn = sprintf(
2160 - '<a href="#" class="lp-metabox-get-final-quiz" data-postid="%d" data-loading="%s">%s</a>',
2161 - $postid,
2162 - esc_attr__( 'Loading...', 'learnpress' ),
2163 - esc_html__( 'Get A Passing Grade', 'learnpress' )
2164 - );
2165 -
2166 - $evaluations_desc = array(
2167 - 'evaluate_lesson' => sprintf(
2168 - '<p>%s<br/>%s</p>',
2169 - __( 'Evaluate by the number of completed lessons per the total number of lessons.', 'learnpress' ),
2170 - __( 'E.g: If a course has 10 lessons and a user completes 5 lessons, then the result is 5/10 (50%).', 'learnpress' )
2171 - ),
2172 - 'evaluate_final_quiz' => __(
2173 - 'Evaluate by the result of the final quiz in the course. You have to add a quiz at the end of the course.',
2174 - 'learnpress'
2175 - ),
2176 - 'evaluate_quiz' => sprintf(
2177 - '<p>%s<br/>%s</p>',
2178 - __( 'Evaluate by the number of passed quizzes per the total number of quizzes.', 'learnpress' ),
2179 - __(
2180 - 'E.g: If the course has 10 quizzes and the user passes 5 quizzes, then the result is 5/10 (50%).',
2181 - 'learnpress'
2182 - )
2183 - ),
2184 - 'evaluate_questions' => sprintf(
2185 - '<p>%s<br/>%s</p>',
2186 - __( 'Evaluate by the number of correct answers per the total number of questions.', 'learnpress' ),
2187 - __(
2188 - 'E.g: If the course has 10 questions and the user corrects 5 questions, then the result is 5/10 (50%).',
2189 - 'learnpress'
2190 - )
2191 - ),
2192 - 'evaluate_mark' => __( 'Evaluate by the number of achieved scores per the total score of the questions.', 'learnpress' ),
2193 - );
2194 -
2195 - $methods = apply_filters(
2196 - 'learnpress/course-evaluation/methods',
2197 - array(
2198 - 'evaluate_lesson' => sprintf(
2199 - '%s %s',
2200 - __( 'Evaluate via lessons', 'learnpress' ),
2201 - learn_press_quick_tip( $evaluations_desc['evaluate_lesson'], false )
2202 - ),
2203 - 'evaluate_final_quiz' => sprintf(
2204 - '%s %s %s %s',
2205 - __( 'Evaluate via results of the final quiz', 'learnpress' ),
2206 - learn_press_quick_tip( $evaluations_desc['evaluate_final_quiz'], false ),
2207 - $final_quiz_btn,
2208 - $final_quizz_passing
2209 - ),
2210 - 'evaluate_quiz' => sprintf(
2211 - '%s %s',
2212 - __( 'Evaluate via passed quizzes', 'learnpress' ),
2213 - learn_press_quick_tip( $evaluations_desc['evaluate_quiz'], false )
2214 - ),
2215 - 'evaluate_questions' => sprintf(
2216 - '%s %s',
2217 - __( 'Evaluate via questions', 'learnpress' ),
2218 - learn_press_quick_tip( $evaluations_desc['evaluate_questions'], false )
2219 - ),
2220 - 'evaluate_mark' => sprintf(
2221 - '%s %s',
2222 - __( 'Evaluate via mark', 'learnpress' ),
2223 - learn_press_quick_tip( $evaluations_desc['evaluate_mark'], false )
2224 - ),
2225 - ),
2226 - $postid
2227 - );
2228 -
2229 - return apply_filters(
2230 - 'learn-press/course-evaluation-methods',
2231 - $return === 'keys' ? array_keys( $methods ) : $methods,
2232 - $return
2233 - );
2234 -}
2235 -
2236 -/**
2237 - * Get max retrying quiz allowed.
2238 - *
2239 - * @param int $quiz_id
2240 - * @param int $course_id
2241 - *
2242 - * @return int
2243 - * @since 4.0.0
2244 - */
2245 -function learn_press_get_quiz_max_retrying( $quiz_id = 0, $course_id = 0 ) {
2246 - return apply_filters( 'learn-press/max-retry-quiz-allowed', 1, $quiz_id, $course_id );
2247 -}
2248 -
2249 -/**
2250 - * Get slug for status of course/lesson/quiz if user
2251 - * completed/finished and graduation is passed.
2252 - *
2253 - * @param string $type
2254 - *
2255 - * @return string
2256 - * @since 4.0.0
2257 - */
2258 -function learn_press_user_item_in_progress_slug( $type = '' ) {
2259 - return apply_filters( 'learn-press/user-item-in-progress-slug', 'in-progress', $type );
2260 -}
2261 -
2262 -/**
2263 - * Get slug for status of course/lesson/quiz if user
2264 - * completed/finished and result is under-evaluation
2265 - *
2266 - * @param string $item - Optional. Type of item
2267 - *
2268 - * @return string
2269 - * @since 4.0.0
2270 - */
2271 -function learn_press_user_item_under_evaluation_slug( $item = '' ) {
2272 - return apply_filters( 'learn-press/user-item-under-evaluation-slug', 'in-progress', $item );
2273 -}
2274 -
2275 -function learn_press_is_enrolled_slug( $slug ) {
2276 - return in_array(
2277 - $slug,
2278 - array(
2279 - 'in-progress',
2280 - 'enrolled',
2281 - )
2282 - );
2283 -}
2284 -
2285 -/**
2286 - * @return array
2287 - * @since 4.0.0
2288 - */
2289 -function lp_item_course_class( $class = array() ) {
2290 - $classes = array_merge(
2291 - $class,
2292 - array( 'learn-press-courses' )
2293 - );
2294 - echo 'class="' . esc_attr( implode( ' ', apply_filters( 'lp_item_course_class', $classes ) ) ) . '"';
2295 -}
2296 -
2297 -//require_once dirname( __FILE__ ) . '/lp-custom-hooks.php';
2298 -
2299 -// Notify update message for LearnPress plugin
2300 -/*add_action(
2301 - 'in_plugin_update_message-learnpress/learnpress.php',
2302 - function ( $plugin_data ) {
2303 - if ( version_compare( $plugin_data['new_version'], LEARNPRESS_VERSION, '<=' ) ) {
2304 - return;
2305 - }
2306 -
2307 - echo sprintf(
2308 - '<hr/><h3>%s</h3><div>%s</div>',
2309 - esc_html__( 'Heads up! Please backup before upgrading!', 'learnpress' ),
2310 - 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' )
2311 - );
2312 - }
2313 -);*/
2314 -
2315 -/**
2316 - * If Elementor Pro set Theme builder type "Archive", will not show content on page "Archive course"
2317 - *
2318 - * @editor tungnx
2319 - * @author nhamdv
2320 - *
2321 - * @since 4.0.6
2322 - * @version 1.0.1
2323 - */
2324 -add_filter(
2325 - 'elementor/theme/get_location_templates/template_id',
2326 - function ( $theme_template_id ) {
2327 - $elementor_template_type = get_post_meta( $theme_template_id, '_elementor_template_type', true );
2328 -
2329 - if ( in_array( $elementor_template_type, array( 'archive' ) ) ) {
2330 - if ( LP_PAGE_COURSES === LP_Page_Controller::page_current() && class_exists( 'ElementorPro\Modules\ThemeBuilder\Conditions\Archive' ) ) {
2331 - return false;
2332 - }
2333 - }
2334 -
2335 - return $theme_template_id;
2336 - }
2337 -);
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 +use LearnPress\Helpers\Config;
12 +
13 +defined( 'ABSPATH' ) || exit;
14 +
15 +/**
16 + * Vue write php has script, so when sanitize will error, so use code is mask pass check sanitize, esc
17 + *
18 + * @param $content
19 + *
20 + * @return void
21 + * @since 4.1.6.9
22 + */
23 +function learn_press_echo_vuejs_write_on_php( $content ) {
24 + echo ( $content );
25 +}
26 +
27 +function learnpress_gutenberg_disable_cpt( $can_edit, $post_type ) {
28 + $post_types = array(
29 + LP_COURSE_CPT => LP_Settings::get_option( 'enable_gutenberg_course', 'no' ),
30 + LP_LESSON_CPT => LP_Settings::get_option( 'enable_gutenberg_lesson', 'no' ),
31 + LP_QUIZ_CPT => LP_Settings::get_option( 'enable_gutenberg_quiz', 'no' ),
32 + LP_QUESTION_CPT => LP_Settings::get_option( 'enable_gutenberg_question', 'no' ),
33 + );
34 +
35 + foreach ( $post_types as $key => $pt ) {
36 + if ( $post_type === $key && $pt !== 'yes' ) {
37 + $can_edit = false;
38 + }
39 + }
40 +
41 + return $can_edit;
42 +}
43 +add_filter( 'use_block_editor_for_post_type', 'learnpress_gutenberg_disable_cpt', 10, 2 );
44 +
45 +if ( ! function_exists( 'lp_add_body_class' ) ) {
46 + function lp_add_body_class( $classes ) {
47 + $classes = (array) $classes;
48 +
49 + if ( LP_Page_Controller::is_page_profile() ) {
50 + $classes[] = 'learnpress-profile';
51 + } elseif ( learn_press_is_checkout() ) {
52 + $classes[] = 'learnpress-checkout';
53 + }
54 +
55 + return $classes;
56 + }
57 + add_filter( 'body_class', 'lp_add_body_class' );
58 +}
59 +
60 +/**
61 + * Short function to get name of a theme
62 + *
63 + * @param string $folder
64 + *
65 + * @return mixed|string
66 + */
67 +function learn_press_get_theme_name( $folder ) {
68 + $theme = wp_get_theme( $folder );
69 +
70 + return ! empty( $theme['Name'] ) ? $theme['Name'] : '';
71 +}
72 +
73 +/**
74 + * Clean.
75 + *
76 + * @param [type] $var
77 + *
78 + * @version 4.0.0
79 + * @author Nhamdv <daonham95@gmail.com>
80 + */
81 +function learnpress_clean( $var ) {
82 + if ( is_array( $var ) ) {
83 + return array_map( 'learnpress_clean', $var );
84 + } else {
85 + return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
86 + }
87 +}
88 +
89 +/**
90 + * Display HTML of element for building QuickTip JS.
91 + *
92 + * @param string $tip
93 + * @param bool $echo
94 + * @param array $options
95 + *
96 + * @return string
97 + * @since 3.0.0
98 + */
99 +function learn_press_quick_tip( $tip, $echo = true, $options = array() ) {
100 + $atts = '';
101 + if ( $options ) {
102 + foreach ( $options as $k => $v ) {
103 + $options[ $k ] = "data-{$k}=\"{$v}\"";
104 + }
105 + $atts = ' ' . implode( ' ', $options );
106 + }
107 +
108 + $tip = sprintf( '<div class="learn-press-tip" ' . $atts . '><span>%s</span></div>', $tip );
109 +
110 + if ( $echo ) {
111 + echo wp_kses_post( $tip );
112 + }
113 +
114 + return $tip;
115 +}
116 +
117 +/**
118 + * Get current post ID.
119 + *
120 + * @return int
121 + */
122 +function learn_press_get_post() {
123 + global $post;
124 +
125 + $post_id = learn_press_get_request( 'post' );
126 +
127 + if ( ! $post_id ) {
128 + $post_id = ! empty( $post ) ? $post->ID : 0;
129 + }
130 + if ( empty( $post_id ) ) {
131 + $post_id = learn_press_get_request( 'post_ID' );
132 + }
133 +
134 + return absint( $post_id );
135 +}
136 +
137 +/**
138 + * Get the LearnPress plugin url
139 + *
140 + * @param string $sub_dir
141 + *
142 + * @return string
143 + */
144 +function learn_press_plugin_url( $sub_dir = '' ) {
145 + return LearnPress::instance()->plugin_url( $sub_dir );
146 +}
147 +
148 +/**
149 + * Get the LearnPress plugin path.
150 + *
151 + * @param string $sub_dir
152 + *
153 + * @return string
154 + */
155 +function learn_press_plugin_path( $sub_dir = '' ) {
156 + return LearnPress::instance()->plugin_path( $sub_dir );
157 +}
158 +
159 +/**
160 + * Includes file base on LearnPress path
161 + *
162 + * @param string $file
163 + * @param string $folder
164 + * @param bool $include_once
165 + *
166 + * @return bool
167 + */
168 +function learn_press_include( $file, $folder = 'inc', $include_once = true ) {
169 + $include = learn_press_plugin_path( "{$folder}/{$file}" );
170 +
171 + if ( file_exists( $include ) ) {
172 + if ( $include_once ) {
173 + include_once $include;
174 + } else {
175 + include $include;
176 + }
177 +
178 + return true;
179 + }
180 +
181 + return false;
182 +}
183 +
184 +/**
185 + * Get current IP of the user
186 + *
187 + * @return mixed
188 + */
189 +function learn_press_get_ip() {
190 + if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
191 + return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) );
192 + } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
193 + // Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
194 + // Make sure we always only send through the first IP in the list which should always be the client IP.
195 + return (string) rest_is_ip_address( trim( current( preg_split( '/,/', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) );
196 + } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
197 + return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
198 + }
199 + return '';
200 +}
201 +
202 +/**
203 + * Get user agent.
204 + *
205 + * @return string
206 + */
207 +function learn_press_get_user_agent(): string {
208 + return LP_Helper::sanitize_params_submitted( $_SERVER['HTTP_USER_AGENT'] ?? '' );
209 +}
210 +
211 +/**
212 + * Generate an unique string.
213 + *
214 + * @param string $prefix
215 + *
216 + * @return string
217 + */
218 +function learn_press_uniqid( $prefix = '' ) {
219 + $hash = str_replace( '.', '', microtime( true ) . uniqid() );
220 +
221 + return apply_filters( 'learn-press/generate-hash', $prefix . $hash, $prefix );
222 +}
223 +
224 +function learn_press_random_value( $len = 8 ) {
225 + return substr( md5( uniqid( mt_rand(), true ) ), 0, $len );
226 +}
227 +
228 +function learn_press_map_columns_format( $columns, $format ) {
229 + $return = array();
230 + foreach ( $columns as $k => $v ) {
231 + if ( ! empty( $format[ $k ] ) ) {
232 + $return[] = $format[ $k ];
233 + } else {
234 + $return[] = '%s'; // default is string
235 + }
236 + }
237 +
238 + return $return;
239 +}
240 +
241 +/**
242 + * Check to see if an endpoint is showing in current URL.
243 + *
244 + * @param bool $endpoint
245 + *
246 + * @return bool
247 + */
248 +function learn_press_is_endpoint_url( $endpoint = false ) {
249 + global $wp;
250 +
251 + $endpoints = array();
252 +
253 + if ( $endpoint !== false ) {
254 + if ( ! isset( $endpoints[ $endpoint ] ) ) {
255 + return false;
256 + } else {
257 + $endpoint_var = $endpoints[ $endpoint ];
258 + }
259 +
260 + return isset( $wp->query_vars[ $endpoint_var ] );
261 + } else {
262 + foreach ( $endpoints as $key => $value ) {
263 + if ( isset( $wp->query_vars[ $key ] ) ) {
264 + return true;
265 + }
266 + }
267 +
268 + return false;
269 + }
270 +}
271 +
272 +/**
273 + * Get current URL user is viewing.
274 + *
275 + * @return string
276 + * @deprecated 4.2.2
277 + */
278 +function learn_press_get_current_url() {
279 + //_deprecated_function( __FUNCTION__, '4.2.2', 'LP_Helper::getUrlCurrent' );
280 + return LP_Helper::getUrlCurrent();
281 +
282 + $url = untrailingslashit( esc_url_raw( $_SERVER['REQUEST_URI'] ) );
283 +
284 + if ( ! preg_match( '!^https?!', $url ) ) {
285 + $siteurl = trailingslashit( get_home_url() );
286 + $home_query = '';
287 +
288 + if ( strpos( $siteurl, '?' ) !== false ) {
289 + $parts = explode( '?', $siteurl );
290 + $home_query = $parts[1];
291 + $siteurl = $parts[0];
292 + }
293 +
294 + if ( $home_query ) {
295 + parse_str( untrailingslashit( $home_query ), $home_query );
296 + $url = esc_url_raw( add_query_arg( $home_query, $url ) );
297 + }
298 +
299 + $segs1 = explode( '/', $siteurl );
300 + $segs2 = explode( '/', $url );
301 +
302 + if ( $removed = array_intersect( $segs1, $segs2 ) ) {
303 + if ( $segs2 = array_diff( $segs2, $removed ) ) {
304 + $current_url = $siteurl . join( '/', $segs2 );
305 + if ( strpos( $current_url, '?' ) === false ) {
306 + $current_url = trailingslashit( $current_url );
307 + }
308 + }
309 + }
310 + }
311 +
312 + return $current_url;
313 +}
314 +
315 +/**
316 + * Remove unneeded characters in an URL
317 + *
318 + * @param string $url
319 + * @param bool $trailingslashit
320 + *
321 + * @return string
322 + */
323 +function learn_press_sanitize_url( $url, $trailingslashit = true ) {
324 + if ( $url ) {
325 + preg_match( '!(https?://)?(.*)!', $url, $matches );
326 + $url_without_http = $matches[2];
327 + $url_without_http = preg_replace( '![/]+!', '/', $url_without_http );
328 + $url = $matches[1] . $url_without_http;
329 +
330 + return ( $trailingslashit &&
331 + strpos( $url, '?' ) === false ) ? trailingslashit( $url ) : untrailingslashit( $url );
332 + }
333 +
334 + return $url;
335 +}
336 +
337 +/**
338 + * Get all types of question supported
339 + *
340 + * @return mixed
341 + */
342 +function learn_press_question_types() {
343 + return LP_Question::get_types();
344 +}
345 +
346 +/**
347 + * Get human name of question's type by slug
348 + *
349 + * @param string $slug
350 + *
351 + * @return array
352 + */
353 +function learn_press_question_name_from_slug( $slug ) {
354 + $types = learn_press_question_types();
355 + $name = ! empty( $types[ $slug ] ) ? $types[ $slug ] : '';
356 +
357 + return apply_filters( 'learn-press/question/slug-to-name', $name, $slug );
358 +}
359 +
360 +/**
361 + * Get terms of a course by taxonomy.
362 + * E.g: course_tag, course_category
363 + *
364 + * @param int $course_id
365 + * @param string $taxonomy
366 + * @param array $args
367 + *
368 + * @return array|mixed
369 + */
370 +function learn_press_get_course_terms( $course_id, $taxonomy, $args = array() ) {
371 + if ( ! taxonomy_exists( $taxonomy ) ) {
372 + return array();
373 + }
374 +
375 + // Support ordering by parent
376 + if ( ! empty( $args['orderby'] ) && in_array( $args['orderby'], array( 'name_num', 'parent' ) ) ) {
377 + $fields = isset( $args['fields'] ) ? $args['fields'] : 'all';
378 + $orderby = $args['orderby'];
379 +
380 + // Unset for wp_get_post_terms
381 + unset( $args['orderby'] );
382 + unset( $args['fields'] );
383 +
384 + $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
385 +
386 + switch ( $orderby ) {
387 + case 'name_num':
388 + usort( $terms, '_learn_press_get_course_terms_name_num_usort_callback' );
389 + break;
390 + case 'parent':
391 + usort( $terms, '_learn_press_get_course_terms_parent_usort_callback' );
392 + break;
393 + }
394 +
395 + switch ( $fields ) {
396 + case 'names':
397 + $terms = wp_list_pluck( $terms, 'name' );
398 + break;
399 + case 'ids':
400 + $terms = wp_list_pluck( $terms, 'term_id' );
401 + break;
402 + case 'slugs':
403 + $terms = wp_list_pluck( $terms, 'slug' );
404 + break;
405 + }
406 + } elseif ( ! empty( $args['orderby'] ) && $args['orderby'] === 'menu_order' ) {
407 + // wp_get_post_terms doesn't let us use custom sort order
408 + $args['include'] = wp_get_post_terms( $course_id, $taxonomy, array( 'fields' => 'ids' ) );
409 +
410 + if ( empty( $args['include'] ) ) {
411 + $terms = array();
412 + } else {
413 + // This isn't needed for get_terms
414 + unset( $args['orderby'] );
415 +
416 + // Set args for get_terms
417 + $args['menu_order'] = $args['order'] ?? 'ASC';
418 + $args['hide_empty'] = $args['hide_empty'] ?? 0;
419 + $args['fields'] = $args['fields'] ?? 'names';
420 +
421 + // Ensure slugs is valid for get_terms - slugs isn't supported
422 + $args['fields'] = $args['fields'] === 'slugs' ? 'id=>slug' : $args['fields'];
423 + $terms = get_terms( $taxonomy, $args );
424 + }
425 + } else {
426 + $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
427 + }
428 +
429 + // @deprecated
430 + $terms = apply_filters( 'learn_press_get_course_terms', $terms, $course_id, $taxonomy, $args );
431 +
432 + return apply_filters( 'learn-press/course/terms', $terms, $course_id, $taxonomy, $args );
433 +}
434 +
435 +/**
436 + * Callback function for sorting terms of course by name.
437 + *
438 + * @param object $a
439 + * @param object $b
440 + *
441 + * @return int
442 + */
443 +function _learn_press_get_course_terms_name_num_usort_callback( $a, $b ) {
444 + if ( $a->name + 0 === $b->name + 0 ) {
445 + return 0;
446 + }
447 +
448 + return ( $a->name + 0 < $b->name + 0 ) ? - 1 : 1;
449 +}
450 +
451 +/**
452 + * Callback function for sorting terms of course by parent.
453 + *
454 + * @param object $a
455 + * @param object $b
456 + *
457 + * @return int
458 + */
459 +function _learn_press_get_course_terms_parent_usort_callback( $a, $b ) {
460 + if ( $a->parent === $b->parent ) {
461 + return 0;
462 + }
463 +
464 + return ( $a->parent < $b->parent ) ? 1 : - 1;
465 +}
466 +
467 +/**
468 + * Get posts by it's post-name (slug).
469 + *
470 + * @param string $name
471 + * @param string $type
472 + * @param bool $single
473 + *
474 + * @return array|bool|null|WP_Post
475 + */
476 +function learn_press_get_post_by_name( $name, $type, $single = true ) {
477 + $post_name = sanitize_title( $name );
478 + $id = LP_Object_Cache::get( $type . '-' . $post_name, 'learn-press/post-names' );
479 +
480 + if ( false === $id ) {
481 + foreach ( array( $name, urldecode( $name ) ) as $_name ) {
482 + $args = array(
483 + 'name' => $_name,
484 + 'post_type' => array( $type ),
485 + );
486 +
487 + $posts = get_posts( $args );
488 +
489 + if ( $posts ) {
490 + $post = $posts[0];
491 + $id = $post->ID;
492 + wp_cache_set( $id, $post, 'posts' );
493 + LP_Object_Cache::set( $type . '-' . $name, $id, 'learn-press/post-names' );
494 + break;
495 + }
496 + }
497 + }
498 +
499 + return $id ? get_post( $id ) : false;
500 +}
501 +
502 +if ( ! function_exists( 'learn_press_is_ajax' ) ) {
503 + function learn_press_is_ajax() {
504 + return defined( 'LP_DOING_AJAX' ) && LP_DOING_AJAX && 'yes' != learn_press_get_request( 'noajax' );
505 + }
506 +}
507 +
508 +/**
509 + * Get page id from admin settings page
510 + *
511 + * @param string $name
512 + *
513 + * @since 3.0.0
514 + * @version 1.0.2
515 + * @return int
516 + */
517 +function learn_press_get_page_id( string $name ): int {
518 + $page_id = LP_Settings::get_option( "{$name}_page_id", false );
519 +
520 + /*if ( function_exists( 'icl_object_id' ) ) {
521 + $page_id = icl_object_id( $page_id, 'page', false, defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : '' );
522 + }*/
523 +
524 + $page_id = (int) $page_id;
525 +
526 + return apply_filters( 'learn_press_get_page_id', $page_id, $name );
527 +}
528 +
529 +/**
530 + * display the seconds in time format h:i:s
531 + *
532 + * @param $seconds
533 + * @param string $separator
534 + *
535 + * @return string
536 + */
537 +function learn_press_seconds_to_time( $seconds, $separator = ':' ) {
538 + return sprintf(
539 + '%02d%s%02d%s%02d',
540 + floor( $seconds / 3600 ),
541 + $separator,
542 + ( $seconds / 60 ) % 60,
543 + $separator,
544 + $seconds % 60
545 + );
546 +}
547 +
548 +/* nav */
549 +if ( ! function_exists( 'learn_press_course_paging_nav' ) ) {
550 +
551 + /**
552 + * Display navigation to next/previous set of posts when applicable.
553 + *
554 + * @param array
555 + */
556 + function learn_press_course_paging_nav( $args = array() ) {
557 + learn_press_paging_nav(
558 + array(
559 + 'num_pages' => $GLOBALS['wp_query']->max_num_pages,
560 + 'wrapper_class' => 'navigation pagination',
561 + )
562 + );
563 + }
564 +}
565 +
566 +/* nav */
567 +if ( ! function_exists( 'learn_press_paging_nav' ) ) {
568 + function learn_press_paging_nav( $args = array() ) {
569 + $args = wp_parse_args(
570 + $args,
571 + array(
572 + 'num_pages' => 0,
573 + 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
574 + 'wrapper_class' => 'learn-press-pagination',
575 + 'base' => false,
576 + 'format' => '',
577 + 'echo' => true,
578 + )
579 + );
580 +
581 + if ( $args['num_pages'] < 2 ) {
582 + return false;
583 + }
584 +
585 + $paged = $args['paged'];
586 + $pagenum_link = html_entity_decode( $args['base'] === false ? get_pagenum_link() : $args['base'] );
587 +
588 + $query_args = array();
589 + $url_parts = explode( '?', $pagenum_link );
590 +
591 + if ( isset( $url_parts[1] ) ) {
592 + wp_parse_str( $url_parts[1], $query_args );
593 + }
594 +
595 + $pagenum_link = esc_url_raw( remove_query_arg( array_keys( $query_args ), $pagenum_link ) );
596 + $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
597 +
598 + $format = $GLOBALS['wp_rewrite']->using_index_permalinks() && ! strpos(
599 + $pagenum_link,
600 + 'index.php'
601 + ) ? 'index.php/' : '';
602 + $format .= $args['format'] ? $args['format'] : ( $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit(
603 + 'page/%#%',
604 + 'paged'
605 + ) : '?paged=%#%' );
606 +
607 + $link_args = array(
608 + 'base' => $pagenum_link,
609 + 'format' => $format,
610 + 'total' => $args['num_pages'],
611 + 'current' => max( 1, $paged ),
612 + 'mid_size' => 1,
613 + 'add_args' => array_map( 'urlencode', $query_args ),
614 + 'prev_text' => __( '<', 'learnpress' ),
615 + 'next_text' => __( '>', 'learnpress' ),
616 + 'type' => 'list',
617 + );
618 +
619 + // Set up paginated links.
620 + $links = paginate_links( $link_args );
621 +
622 + ob_start();
623 +
624 + if ( $links ) {
625 + ?>
626 + <div class="<?php echo esc_attr( $args['wrapper_class'] ); ?>">
627 + <?php echo wp_kses_post( $links ); ?>
628 + </div>
629 + <?php
630 + }
631 +
632 + $output = ob_get_clean();
633 +
634 + if ( $args['echo'] ) {
635 + echo wp_kses_post( $output );
636 + }
637 +
638 + return $output;
639 + }
640 +}
641 +
642 +/**
643 + * Get number of pages by rows and items per page.
644 + *
645 + * @param int $total
646 + * @param int $limit
647 + *
648 + * @return int
649 + */
650 +function learn_press_get_num_pages( $total, $limit = 10 ) {
651 + $limit = $limit <= 0 ? 10 : $limit;
652 +
653 + if ( $total <= $limit ) {
654 + return 1;
655 + }
656 +
657 + $pages = absint( $total / $limit );
658 +
659 + if ( $total % $limit != 0 ) {
660 + ++$pages;
661 + }
662 +
663 + return $pages;
664 +}
665 +
666 +/**
667 + * Get text
668 + *
669 + * @param $status_id
670 + *
671 + * @return mixed
672 + */
673 +function learn_press_get_status_text( $status_id ) {
674 + switch ( $status_id ) {
675 + case 1:
676 + $text = 'pending';
677 + break;
678 + case 2:
679 + $text = 'complete';
680 + break;
681 + case - 1:
682 + $text = 'cancel';
683 + break;
684 + case - 2:
685 + $text = 'refund';
686 + break;
687 + default:
688 + $text = 'on-hold';
689 + }
690 +
691 + return $text;
692 +}
693 +
694 +function learn_press_get_course_duration_support() {
695 + return apply_filters(
696 + 'learn_press_course_duration_support',
697 + array(
698 + 'minute' => esc_html__( 'Minute(s)', 'learnpress' ),
699 + 'hour' => esc_html__( 'Hour(s)', 'learnpress' ),
700 + 'day' => esc_html__( 'Day(s)', 'learnpress' ),
701 + 'week' => esc_html__( 'Week(s)', 'learnpress' ),
702 + )
703 + );
704 +}
705 +
706 +function learn_press_number_to_string_time( $number ) {
707 + $str = $number;
708 +
709 + if ( preg_match( '!([0-9.]+) (minute|hour|day|week)!', $number, $matches ) ) {
710 + switch ( $matches[2] ) {
711 + case 'hour':
712 + $minute = $matches[1] * 60;
713 + $str = sprintf( '%s hour %s minute', absint( $minute / 60 ), $minute % 60 );
714 + break;
715 + case 'day':
716 + $hour = $matches[1] * 24;
717 + $str = sprintf( '%s day %s hour', absint( $hour / 24 ), $hour % 24 );
718 + break;
719 + case 'week':
720 + $day = $matches[1] * 7;
721 + $str = sprintf( '%s week %s day', absint( $day / 7 ), $day % 7 );
722 + break;
723 + }
724 + }
725 +
726 + return $str;
727 +}
728 +
729 +function learn_press_human_time_to_seconds( $time, $default = '' ) {
730 + $duration = learn_press_get_course_duration_support();
731 + $duration_keys = array_keys( $duration );
732 +
733 + if ( preg_match_all( '!([0-9]+)\s*(' . join( '|', $duration_keys ) . ')?!', $time, $matches ) ) {
734 + $a1 = $matches[1][0];
735 + $a2 = in_array( $matches[2][0], $duration_keys ) ? $matches[2][0] : '';
736 + } else {
737 + $a1 = absint( $time );
738 + $a2 = '';
739 + }
740 +
741 + if ( $a2 ) {
742 + $b = array(
743 + 'minute' => 60,
744 + 'hour' => 3600,
745 + 'day' => 3600 * 24,
746 + 'week' => 3600 * 24 * 7,
747 + );
748 + $a1 = $a1 * $b[ $a2 ];
749 + }
750 +
751 + return $a1;
752 +}
753 +
754 +/**
755 + * @param $user_id
756 + *
757 + * @return WP_Query
758 + */
759 +function learn_press_get_own_courses( $user_id ) {
760 + $arr_query = array(
761 + 'post_type' => 'lp_course',
762 + 'author' => $user_id,
763 + 'post_status' => 'publish',
764 + 'ignore_sticky_posts' => true,
765 + 'posts_per_page' => - 1,
766 + );
767 + $my_query = new WP_Query( $arr_query );
768 +
769 + return $my_query;
770 +}
771 +
772 +/**
773 + * Return array list of currency positions.
774 + *
775 + * @param bool|string $currency
776 + *
777 + * @return array
778 + */
779 +function learn_press_currency_positions( $currency = false ) {
780 + $positions = array(
781 + 'left' => __( 'Left', 'learnpress' ),
782 + 'right' => __( 'Right', 'learnpress' ),
783 + 'left_with_space' => __( 'Left with space', 'learnpress' ),
784 + 'right_with_space' => __( 'Right with space', 'learnpress' ),
785 + );
786 +
787 + if ( false === $currency ) {
788 + $currency = learn_press_get_currency_symbol();
789 + }
790 +
791 + $settings = LP_Settings::instance();
792 +
793 + $thousands_separator = '';
794 + $decimals_separator = $settings->get( 'decimals_separator', '.' );
795 + $number_of_decimals = $settings->get( 'number_of_decimals', 2 );
796 +
797 + if ( $number_of_decimals > 0 ) {
798 + $example = '69' . $decimals_separator . str_repeat( '9', $number_of_decimals );
799 + } else {
800 + $example = '69';
801 + }
802 +
803 + foreach ( $positions as $pos => $text ) {
804 + switch ( $pos ) {
805 + case 'left':
806 + $text = sprintf( '%s ( %s%s )', $text, $currency, $example );
807 + break;
808 + case 'right':
809 + $text = sprintf( '%s ( %s%s )', $text, $example, $currency );
810 + break;
811 + case 'left_with_space':
812 + $text = sprintf( '%s ( %s %s )', $text, $currency, $example );
813 + break;
814 + case 'right_with_space':
815 + $text = sprintf( '%s ( %s %s )', $text, $example, $currency );
816 + break;
817 + }
818 + $positions[ $pos ] = $text;
819 + }
820 +
821 + $positions = apply_filters( 'learn_press_currency_positions', $positions );
822 +
823 + return apply_filters( 'learn-press/currency-positions', $positions );
824 +}
825 +
826 +/**
827 + * @return array
828 + */
829 +function learn_press_get_payment_currencies() {
830 + return apply_filters( 'learn_press_get_payment_currencies', learn_press_currencies() );
831 +}
832 +
833 +/**
834 + * Get the list of currencies with code and name.
835 + *
836 + * @return array
837 + * @version 3.0.1
838 + *
839 + * @author ThimPress
840 + */
841 +function learn_press_currencies() {
842 + return Config::instance()->get( 'currencies', 'settings' );
843 +}
844 +
845 +/**
846 + * Return list of common symbols of the currencies on the world.
847 + *
848 + * @return array
849 + * @version 3.0.1
850 + */
851 +function learn_press_currency_symbols() {
852 + return Config::instance()->get( 'currency-symbols', 'settings' );
853 +}
854 +
855 +/**
856 + * Get current setting of currency.
857 + *
858 + * @return string
859 + */
860 +function learn_press_get_currency(): string {
861 + $currency = LP_Settings::instance()->get( 'currency', 'USD' );
862 +
863 + return esc_html( apply_filters( 'learn-press/currency', $currency ) );
864 +}
865 +
866 +/**
867 + * Return currency symbol from the code.
868 + *
869 + * @param string $currency
870 + *
871 + * @return string
872 + */
873 +function learn_press_get_currency_symbol( $currency = '' ) {
874 + if ( ! $currency ) {
875 + $currency = learn_press_get_currency();
876 + }
877 + $symbols = learn_press_currency_symbols();
878 + $currency_symbol = $symbols[ $currency ] ?? '';
879 +
880 + $currency_symbol = apply_filters( 'learn_press_currency_symbol', $currency_symbol, $currency );
881 +
882 + return apply_filters( 'learn-press/currency-symbol', $currency_symbol, $currency );
883 +}
884 +
885 +/**
886 + * Get static page for LP page by name.
887 + *
888 + * @param string $key
889 + *
890 + * @return string
891 + * @editor tungnx
892 + * @modify 4.1.4
893 + */
894 +function learn_press_get_page_link( string $key ): string {
895 + $page_id = learn_press_get_page_id( $key );
896 + $key_cache = "lp/page-link/{$key}";
897 + $link = LP_Cache::cache_load_first( 'get', $key_cache );
898 + if ( false !== $link ) {
899 + return $link;
900 + }
901 +
902 + if ( $page_id && get_post_status( $page_id ) == 'publish' ) {
903 + $permalink = get_permalink( $page_id );
904 + $link = apply_filters( 'learn-press/get-page-link', trailingslashit( $permalink ), $page_id, $key );
905 + LP_Cache::cache_load_first( 'set', $key_cache, $link );
906 + }
907 +
908 + return $link;
909 +}
910 +
911 +/**
912 + * Get static page for LP page by name.
913 + *
914 + * @param string $key
915 + *
916 + * @return string
917 + */
918 +function learn_press_get_page_title( $key ) {
919 + $page_id = LP_Settings::instance()->get( $key . '_page_id' );
920 + $title = '';
921 +
922 + if ( $page_id && get_post_status( $page_id ) == 'publish' ) {
923 + $title = apply_filters( 'learn-press/get-page-title', get_the_title( $page_id ), $page_id, $key );
924 + }
925 +
926 + return apply_filters( 'learn-press/get-page-' . $key . '-title', $title, $page_id );
927 +}
928 +
929 +/**
930 + * get the ID of a course by order ID
931 + *
932 + * @param $order_id
933 + *
934 + * @return bool|mixed
935 + */
936 +function learn_press_get_course_by_order( $order_id ) {
937 + $order_items = get_post_meta( $order_id, '_learn_press_order_items', true );
938 +
939 + if ( $order_items && $order_items->products ) {
940 + $array_keys = array_keys( $order_items->products );
941 +
942 + return reset( $array_keys );
943 + }
944 +
945 + return false;
946 +}
947 +
948 +/**
949 + * Convert a number of seconds to weeks/days/hours.
950 + *
951 + * @param int $secs
952 + *
953 + * @return bool|string
954 + */
955 +function learn_press_seconds_to_weeks( int $secs = 0 ) {
956 + $secs = (int) $secs;
957 +
958 + if ( 0 === $secs ) {
959 + return false;
960 + }
961 + // variables for holding values.
962 + $mins = 0;
963 + $hours = 0;
964 + $days = 0;
965 + $weeks = 0;
966 + // calculations.
967 + if ( $secs >= 60 ) {
968 + $mins = (int) ( $secs / 60 );
969 + $secs = $secs % 60;
970 + }
971 + if ( $mins >= 60 ) {
972 + $hours = (int) ( $mins / 60 );
973 + $mins = $mins % 60;
974 + }
975 + if ( $hours >= 24 ) {
976 + $days = (int) ( $hours / 24 );
977 + $hours = $hours % 24;
978 + }
979 + if ( $days >= 7 ) {
980 + $weeks = (int) ( $days / 7 );
981 + $days = $days % 7;
982 + }
983 + // format result.
984 + $result = '';
985 + if ( $weeks ) {
986 + $result .= sprintf( _n( '%s week', '%s weeks', $weeks, 'learnpress' ), $weeks ) . ' ';
987 + }
988 +
989 + if ( $days ) {
990 + $result .= sprintf( _n( '%s day', '%s days', $days, 'learnpress' ), $days ) . ' ';
991 + }
992 +
993 + if ( ! $weeks ) {
994 + if ( $hours ) {
995 + $result .= sprintf( _n( '%s hour', '%s hours', $hours, 'learnpress' ), $hours ) . ' ';
996 + }
997 +
998 + if ( $mins ) {
999 + $result .= sprintf( _n( '%s minute', '%s minutes', $mins, 'learnpress' ), $mins ) . ' ';
1000 + }
1001 + }
1002 +
1003 + $result = rtrim( $result );
1004 +
1005 + return $result;
1006 +}
1007 +
1008 +function learn_press_user_maybe_is_a_teacher( $user = null ) {
1009 + if ( ! $user ) {
1010 + $user = learn_press_get_current_user();
1011 + } elseif ( is_numeric( $user ) ) {
1012 + $user = learn_press_get_user( $user );
1013 + }
1014 + if ( ! $user || $user instanceof LP_User_Guest ) {
1015 + return false;
1016 + }
1017 +
1018 + $role = $user->has_role( 'administrator' ) ? 'administrator' : false;
1019 + if ( ! $role ) {
1020 + $role = $user->has_role( 'lp_teacher' ) ? 'lp_teacher' : false;
1021 + }
1022 +
1023 + return apply_filters( 'learn-press/user/is-teacher', $role, $user->get_id() );
1024 +}
1025 +
1026 +function learn_press_become_teacher_sent( $user_id = 0 ) {
1027 + if ( func_num_args() == 0 ) {
1028 + $user_id = get_current_user_id();
1029 + }
1030 +
1031 + return 'yes' === get_user_meta( $user_id, '_requested_become_teacher', true );
1032 +}
1033 +
1034 +function _learn_press_translate_user_roles( $translations, $text, $context, $domain ) {
1035 + $plugin_domain = 'learnpress';
1036 + $roles = array( 'LP Instructor' );
1037 +
1038 + if ( $context === 'User role' && in_array( $text, $roles ) && $domain !== $plugin_domain ) {
1039 + return translate_with_gettext_context( $text, $context, $plugin_domain );
1040 + }
1041 +
1042 + return $translations;
1043 +}
1044 +
1045 +add_filter( 'gettext_with_context', '_learn_press_translate_user_roles', 10, 4 );
1046 +
1047 +if ( ! function_exists( 'learn_press_send_json' ) ) {
1048 + function learn_press_send_json( $data ) {
1049 + echo '<-- LP_AJAX_START -->';
1050 + echo wp_json_encode( $data );
1051 + echo '<-- LP_AJAX_END -->';
1052 + die;
1053 + }
1054 +}
1055 +
1056 +/**
1057 + * Send json with success signal to browser.
1058 + *
1059 + * @param array|object|WP_Error $data
1060 + *
1061 + * @since 3.0.1
1062 + */
1063 +function learn_press_send_json_error( $data = '' ) {
1064 + $response = array( 'success' => false );
1065 +
1066 + if ( isset( $data ) ) {
1067 + if ( is_wp_error( $data ) ) {
1068 + $result = array();
1069 + foreach ( $data->errors as $code => $messages ) {
1070 + foreach ( $messages as $message ) {
1071 + $result[] = array(
1072 + 'code' => $code,
1073 + 'message' => $message,
1074 + );
1075 + }
1076 + }
1077 +
1078 + $response['data'] = $result;
1079 + } else {
1080 + $response['data'] = $data;
1081 + }
1082 + }
1083 +
1084 + learn_press_send_json( $response );
1085 +}
1086 +
1087 +/**
1088 + * Send json with error signal to browser.
1089 + *
1090 + * @param array|object|WP_Error $data
1091 + *
1092 + * @since 3.0.0
1093 + */
1094 +function learn_press_send_json_success( $data = '' ) {
1095 + $response = array( 'success' => true );
1096 +
1097 + if ( isset( $data ) ) {
1098 + $response['data'] = $data;
1099 + }
1100 +
1101 + learn_press_send_json( $response );
1102 +}
1103 +
1104 +/**
1105 + * Check if ajax is calling then send json data.
1106 + *
1107 + * @param array $data
1108 + * @param mixed $callback
1109 + *
1110 + * @return bool
1111 + */
1112 +function learn_press_maybe_send_json( $data, $callback = null ) {
1113 + if ( learn_press_is_ajax() ) {
1114 + is_callable( $callback ) && call_user_func( $callback );
1115 + $message = learn_press_get_messages( true );
1116 + if ( empty( $data['message'] ) && $message ) {
1117 + $data['message'] = $message;
1118 + }
1119 + learn_press_send_json( $data );
1120 + }
1121 +
1122 + return false;
1123 +}
1124 +
1125 +/**
1126 + * Get data from request.
1127 + *
1128 + * @param string $key
1129 + * @param mixed $default
1130 + * @param mixed $hash
1131 + *
1132 + * @return mixed
1133 + */
1134 +function learn_press_get_request( $key, $default = null, $hash = null ) {
1135 + $return = $default;
1136 +
1137 + if ( $hash ) {
1138 + if ( ! empty( $hash[ $key ] ) ) {
1139 + $return = $hash[ $key ];
1140 + }
1141 + } else {
1142 + if ( ! empty( $_POST[ $key ] ) ) {
1143 + $return = LP_Helper::sanitize_params_submitted( $_POST[ $key ] );
1144 + } elseif ( ! empty( $_GET[ $key ] ) ) {
1145 + $return = LP_Helper::sanitize_params_submitted( $_GET[ $key ] );
1146 + } elseif ( ! empty( $_REQUEST[ $key ] ) ) {
1147 + $return = LP_Helper::sanitize_params_submitted( $_REQUEST[ $key ] );
1148 + }
1149 + }
1150 +
1151 + return $return;
1152 +}
1153 +
1154 +/**
1155 + * @return mixed
1156 + */
1157 +function is_learnpress() {
1158 + return apply_filters(
1159 + 'is_learnpress',
1160 + ( learn_press_is_course_archive() || learn_press_is_course_taxonomy() || learn_press_is_course() || learn_press_is_quiz() || learn_press_is_search() ) ? true : false
1161 + );
1162 +}
1163 +
1164 +if ( ! function_exists( 'learn_press_is_search' ) ) {
1165 + function learn_press_is_search() {
1166 + return array_key_exists( 's', $_REQUEST ) && array_key_exists( 'ref', $_REQUEST ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course';
1167 + }
1168 +}
1169 +
1170 +if ( ! function_exists( 'learn_press_is_courses' ) ) {
1171 + function learn_press_is_courses() {
1172 + return learn_press_is_course_archive();
1173 + }
1174 +}
1175 +
1176 +
1177 +if ( ! function_exists( 'learn_press_is_course_archive' ) ) {
1178 + function learn_press_is_course_archive() {
1179 + global $wp_query;
1180 +
1181 + $queried_object_id = ! empty( $wp_query->queried_object ) ? $wp_query->queried_object : 0;
1182 + $is_tag = defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG || is_tax( 'course_tag' );
1183 + $is_category = defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY || is_tax( 'course_category' );
1184 + $page_id = learn_press_get_page_id( 'courses' );
1185 +
1186 + return ( $is_category || $is_tag ) || is_post_type_archive( 'lp_course' ) || ( $page_id && ( $queried_object_id && is_page( $page_id ) ) );
1187 + }
1188 +}
1189 +
1190 +if ( ! function_exists( 'learn_press_is_course_tax' ) ) {
1191 + function learn_press_is_course_tax() {
1192 + return is_tax( get_object_taxonomies( LP_COURSE_CPT ) );
1193 + }
1194 +}
1195 +
1196 +if ( ! function_exists( 'learn_press_is_course_taxonomy' ) ) {
1197 + function learn_press_is_course_taxonomy() {
1198 + return ( defined( 'LEARNPRESS_IS_TAX' ) && LEARNPRESS_IS_TAX ) || learn_press_is_course_tax();
1199 + }
1200 +}
1201 +
1202 +
1203 +if ( ! function_exists( 'learn_press_is_course_category' ) ) {
1204 + function learn_press_is_course_category( $term = '' ) {
1205 + return ( defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY ) || is_tax( 'course_category', $term );
1206 + }
1207 +}
1208 +
1209 +
1210 +if ( ! function_exists( 'learn_press_is_course_tag' ) ) {
1211 + function learn_press_is_course_tag( $term = '' ) {
1212 + return ( defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG ) || is_tax( 'course_tag', $term );
1213 + }
1214 +}
1215 +
1216 +if ( ! function_exists( 'learn_press_is_course' ) ) {
1217 + function learn_press_is_course(): bool {
1218 + try {
1219 + return is_singular( array( LP_COURSE_CPT ) );
1220 + } catch ( Throwable $e ) {
1221 + }
1222 +
1223 + return false;
1224 + }
1225 +}
1226 +
1227 +if ( ! function_exists( 'learn_press_is_lesson' ) ) {
1228 + function learn_press_is_lesson() {
1229 + return is_singular( array( LP_LESSON_CPT ) );
1230 + }
1231 +}
1232 +
1233 +if ( ! function_exists( 'learn_press_is_quiz' ) ) {
1234 + function learn_press_is_quiz() {
1235 + return is_singular( array( LP_QUIZ_CPT ) );
1236 + }
1237 +}
1238 +
1239 +function lp_content_has_shortcode( $tag = '' ) {
1240 + global $post;
1241 +
1242 + return is_singular() && is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, $tag );
1243 +}
1244 +
1245 +/**
1246 + * Returns true when viewing profile page.
1247 + *
1248 + * @return bool
1249 + */
1250 +function learn_press_is_profile() {
1251 + $page_id = learn_press_get_page_id( 'profile' );
1252 +
1253 + if ( $page_id && is_page( $page_id ) || lp_content_has_shortcode( 'learn_press_profile' ) ) {
1254 + return true;
1255 + }
1256 +
1257 + return apply_filters( 'learn-press/is-profile', false );
1258 +}
1259 +
1260 +/**
1261 + * Return true if user is in checking out page
1262 + *
1263 + * @return bool
1264 + */
1265 +function learn_press_is_checkout() {
1266 + $page_id = learn_press_get_page_id( 'checkout' );
1267 +
1268 + if ( $page_id && is_page( $page_id ) ) {
1269 + return true;
1270 + }
1271 +
1272 + return apply_filters( 'learn-press/is-checkout', false );
1273 +}
1274 +
1275 +function learn_press_is_instructors() {
1276 + $page_id = learn_press_get_page_id( 'instructors' );
1277 +
1278 + if ( $page_id && is_page( $page_id ) ) {
1279 + return true;
1280 + }
1281 +
1282 + return apply_filters( 'learn-press/is-instructor', false );
1283 +}
1284 +
1285 +
1286 +/**
1287 + * Return register permalink
1288 + *
1289 + * @return mixed
1290 + */
1291 +function learn_press_get_register_url() {
1292 + return apply_filters( 'learn_press_register_url', wp_registration_url() );
1293 +}
1294 +
1295 +/**
1296 + * Add a new notice into queue
1297 + *
1298 + * @param string
1299 + * @param string
1300 + *
1301 + * @return mixed
1302 + * @deprecated 4.2.5
1303 + */
1304 +function learn_press_add_notice( $message, $type = 'updated' ) {
1305 + _deprecated_function( __FUNCTION__, '4.2.5' );
1306 + LP_Admin_Notice::instance()->add( $message, $type );
1307 +}
1308 +
1309 +/**
1310 + * Set user's cookie
1311 + *
1312 + * @param string $name
1313 + * @param mixed $value
1314 + * @param int $expire
1315 + * @param bool $httponly
1316 + *
1317 + * @editor tungnx
1318 + * @version 1.0.3
1319 + */
1320 +function learn_press_setcookie( string $name = '', string $value = '', int $expire = 0, bool $httponly = true ) {
1321 + @setcookie( $name, $value, $expire, COOKIEPATH ?: '/', COOKIE_DOMAIN, is_ssl(), $httponly );
1322 +}
1323 +
1324 +/**
1325 + * Clear cookie
1326 + *
1327 + * @param string $name
1328 + */
1329 +function learn_press_remove_cookie( string $name = '' ) {
1330 + if ( ! empty( $name ) ) {
1331 + setcookie( $name, '', time() - YEAR_IN_SECONDS, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, is_ssl(), true );
1332 + }
1333 +
1334 + if ( array_key_exists( $name, $_COOKIE ) ) {
1335 + unset( $_COOKIE[ $name ] );
1336 + }
1337 +}
1338 +
1339 +/**
1340 + * Filter the login url so third-party can be customized
1341 + *
1342 + * @param string $redirect
1343 + *
1344 + * @return mixed
1345 + */
1346 +function learn_press_get_login_url( $redirect = null ) {
1347 + $url = wp_login_url( $redirect );
1348 + $profile_page = learn_press_get_page_link( 'profile' );
1349 +
1350 + if ( 'yes' === LP_Settings::instance()->get( 'enable_login_profile' ) && $profile_page ) {
1351 + $parse_url = parse_url( $url );
1352 + $url = $profile_page . ( ! empty( $parse_url['query'] ) ? '?' . $parse_url['query'] : '' );
1353 + }
1354 +
1355 + return apply_filters( 'learn-press/login-url', $url );
1356 +}
1357 +
1358 +/**
1359 + * Add variable to an url by checking the permalink structure.
1360 + *
1361 + * @param string $name
1362 + * @param string $value
1363 + * @param string $url
1364 + *
1365 + * @return string
1366 + */
1367 +function learn_press_get_endpoint_url( $name, $value, $url ) {
1368 + if ( ! $url ) {
1369 + $url = get_permalink();
1370 + }
1371 +
1372 + // Map endpoint to options
1373 + $name = isset( LearnPress::instance()->query_vars[ $name ] ) ? LearnPress::instance()->query_vars[ $name ] : $name;
1374 +
1375 + if ( get_option( 'permalink_structure' ) ) {
1376 + if ( strstr( $url, '?' ) ) {
1377 + $query_string = '?' . parse_url( $url, PHP_URL_QUERY );
1378 + $url = current( explode( '?', $url ) );
1379 + } else {
1380 + $query_string = '';
1381 + }
1382 + $url = trailingslashit( $url ) . ( $name ? $name . '/' : '' ) . $value . $query_string;
1383 +
1384 + } else {
1385 + $url = esc_url_raw( add_query_arg( $name, $value, $url ) );
1386 + }
1387 +
1388 + return apply_filters( 'learn_press_get_endpoint_url', esc_url_raw( $url ), $name, $value, $url );
1389 +}
1390 +
1391 +/**
1392 + * @deprecated 4.2.3
1393 + */
1394 +function learn_press_is_yes( $value ) {
1395 + _deprecated_function( __FUNCTION__, '4.2.3' );
1396 + return ( $value === 1 ) || ( $value === '1' ) || ( $value == 'yes' ) || ( $value == true ) || ( $value == 'on' );
1397 +}
1398 +
1399 +/**
1400 + * @param mixed $value
1401 + *
1402 + * @return bool
1403 + * @deprecated 4.2.3
1404 + */
1405 +function _is_false_value( $value ) {
1406 + _deprecated_function( __FUNCTION__, '4.2.3' );
1407 + if ( is_numeric( $value ) ) {
1408 + return $value == 0;
1409 + } elseif ( is_string( $value ) ) {
1410 + return ( empty( $value ) || is_null( $value ) || in_array( $value, array( 'no', 'off', 'false' ) ) );
1411 + }
1412 +
1413 + return ! ! $value;
1414 +}
1415 +
1416 +/**
1417 + * Map the query vars from LP to query vars of WP core
1418 + * when WP parse the requesting.
1419 + */
1420 +function learn_press_parse_request() {
1421 + global $wp;
1422 +
1423 + // Map query vars to their keys, or get them if endpoints are not supported
1424 + foreach ( LearnPress::instance()->query_vars as $key => $var ) {
1425 + if ( isset( $_GET[ $var ] ) ) {
1426 + $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $_GET[ $var ] ?? '' );
1427 + } elseif ( isset( $wp->query_vars[ $var ] ) ) {
1428 + $wp->query_vars[ $key ] = LP_Helper::sanitize_params_submitted( $wp->query_vars[ $var ] ?? '' );
1429 + }
1430 + }
1431 +}
1432 +
1433 +add_action( 'parse_request', 'learn_press_parse_request' );
1434 +
1435 +if ( ! function_exists( 'learn_press_reset_auto_increment' ) ) {
1436 + /**
1437 + * Reset AUTO INCREMENT of the table.
1438 + *
1439 + * @param $table
1440 + */
1441 + function learn_press_reset_auto_increment( $table ) {
1442 + global $wpdb;
1443 + $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}$table AUTO_INCREMENT = %d", 1 ) );
1444 + }
1445 +}
1446 +
1447 +/**
1448 + * Get the cart object in checkout page
1449 + *
1450 + * @return LP_Cart
1451 + * @deprecated 4.2.0
1452 + */
1453 +function learn_press_get_checkout_cart() {
1454 + _deprecated_function( __FUNCTION__, '4.2.0', 'LearnPress::instance()->cart' );
1455 + return apply_filters( 'learn_press_checkout_cart', LearnPress::instance()->cart );
1456 +}
1457 +
1458 +function learn_press_user_time( $time, $format = 'timestamp' ) {
1459 + if ( is_string( $time ) ) {
1460 + $time = @strtotime( $time );
1461 + }
1462 + $time = $time + ( get_option( 'gmt_offset' ) - $_COOKIE['timezone'] / 60 ) * HOUR_IN_SECONDS;
1463 + switch ( $format ) {
1464 + case 'timestamp':
1465 + return $time;
1466 + default:
1467 + return date( 'Y-m-d H:i:s', $time );
1468 + }
1469 +}
1470 +
1471 +function learn_press_get_current_version() {
1472 + $data = get_plugin_data( LP_PLUGIN_FILE, $markup = true, $translate = true );
1473 +
1474 + return $data['Version'];
1475 +}
1476 +
1477 +/**
1478 + * Get current tab is displaying in user profile.
1479 + * If there is no tab then get the first tab in
1480 + * the list of tabs.
1481 + *
1482 + * @param bool $default
1483 + *
1484 + * @return mixed|string
1485 + * @deprecated 4.2.2
1486 + * addon commission 4.0.2 still use this function
1487 + */
1488 +function learn_press_get_current_profile_tab( $default = true ) {
1489 + global $wp_query, $wp;
1490 + $current = '';
1491 +
1492 + // Only load on profile page.
1493 + if ( ! LP_Page_Controller::is_page_profile() ) {
1494 + return false;
1495 + }
1496 +
1497 + if ( ! empty( $_REQUEST['tab'] ) ) {
1498 + $current = LP_Helper::sanitize_params_submitted( $_REQUEST['tab'] );
1499 + } elseif ( ! empty( $wp_query->query_vars['tab'] ) ) {
1500 + $current = $wp_query->query_vars['tab'];
1501 + } elseif ( ! empty( $wp->query_vars['view'] ) ) {
1502 + $current = $wp->query_vars['view'];
1503 + } else {
1504 + $tabs = learn_press_get_user_profile_tabs();
1505 + if ( $default && $tabs ) {
1506 + // Fixed for array_keys does not work with ArrayAccess instance
1507 + if ( $tabs instanceof LP_Profile_Tabs ) {
1508 + $tabs = $tabs->tabs();
1509 + }
1510 +
1511 + $tab_keys = array_keys( $tabs );
1512 + $current = reset( $tab_keys );
1513 + }
1514 + }
1515 +
1516 + return $current;
1517 +}
1518 +
1519 +//add_action( 'init', 'learn_press_get_current_profile_tab' );
1520 +
1521 +function learn_press_profile_tab_exists( $tab ) {
1522 + $tabs = learn_press_get_user_profile_tabs();
1523 +
1524 + if ( $tabs ) {
1525 + return ! empty( $tabs[ $tab ] ) ? true : false;
1526 + }
1527 +
1528 + return false;
1529 +}
1530 +
1531 +function learn_press_single_term_title( $prefix = '', $display = true ) {
1532 + $term = get_queried_object();
1533 +
1534 + if ( ! $term ) {
1535 + return '';
1536 + }
1537 +
1538 + if ( learn_press_is_course_category() ) {
1539 + $term_name = apply_filters( 'single_course_category_title', $term->name );
1540 + } elseif ( learn_press_is_course_tag() ) {
1541 + $term_name = apply_filters( 'single_course_tag_title', $term->name );
1542 + } elseif ( learn_press_is_course_taxonomy() ) {
1543 + $term_name = apply_filters( 'single_course_term_title', $term->name );
1544 + } else {
1545 + return single_term_title( $prefix, $display );
1546 + }
1547 +
1548 + if ( empty( $term_name ) ) {
1549 + return single_term_title( $prefix, $display );
1550 + }
1551 +
1552 + if ( $display ) {
1553 + echo wp_kses_post( $prefix . $term_name );
1554 + }
1555 +
1556 + return $prefix . $term_name;
1557 +}
1558 +
1559 +/**
1560 + * Control the template file if user is searching course.
1561 + * Use the template of archive course to display the
1562 + * result if there is a flag in request to search course.
1563 + *
1564 + * @param string $template
1565 + *
1566 + * @return string
1567 + */
1568 +function learn_press_search_template( $template ) {
1569 + if ( ! empty( $_REQUEST['ref'] ) && sanitize_text_field( $_REQUEST['ref'] ) == 'course' ) {
1570 + $template = learn_press_locate_template( 'archive-course.php' );
1571 + }
1572 +
1573 + return $template;
1574 +}
1575 +
1576 +/**
1577 + * Auto enroll user to a course after an order is completed
1578 + * if the option auto-enroll is turn on.
1579 + *
1580 + * @param int $order_id
1581 + *
1582 + * @return mixed
1583 + * @editor tungnx
1584 + */
1585 +function learn_press_auto_enroll_user_to_courses( $order_id ) {
1586 + _deprecated_function( __FUNCTION__, '4.1.3' );
1587 +}
1588 +
1589 +// add_action( 'learn_press_order_status_completed', 'learn_press_auto_enroll_user_to_courses' );
1590 +
1591 +/**
1592 + * Return true if enable cart
1593 + *
1594 + * @return bool
1595 + */
1596 +function learn_press_is_enable_cart() {
1597 + return defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART == true;
1598 +}
1599 +
1600 +/**
1601 + * Short way to get checkout object
1602 + *
1603 + * @param array
1604 + *
1605 + * @return LP_Checkout
1606 + */
1607 +function learn_press_get_checkout( $args = null ) {
1608 + $checkout = LP_Checkout::instance();
1609 +
1610 + if ( is_array( $args ) ) {
1611 + foreach ( $args as $k => $v ) {
1612 + $checkout->{$k} = $v;
1613 + }
1614 + }
1615 +
1616 + return $checkout;
1617 +}
1618 +
1619 +if ( defined( 'LP_ENABLE_CART' ) && LP_ENABLE_CART ) {
1620 + add_filter( 'learn_press_checkout_settings', '_learn_press_cart_settings', 10, 2 );
1621 + function _learn_press_cart_settings( $settings, $class ) {
1622 + $settings = array_merge(
1623 + $settings,
1624 + array(
1625 + array(
1626 + 'title' => __( 'Cart', 'learnpress' ),
1627 + 'type' => 'title',
1628 + ),
1629 + array(
1630 + 'title' => __( 'Enable cart', 'learnpress' ),
1631 + 'desc' => __(
1632 + 'Check this option to enable users to purchase multiple courses at one time.',
1633 + 'learnpress'
1634 + ),
1635 + 'id' => $class->get_field_name( 'enable_cart' ),
1636 + 'default' => 'yes',
1637 + 'type' => 'checkbox',
1638 + ),
1639 + array(
1640 + 'title' => __( 'Add to cart redirect', 'learnpress' ),
1641 + 'desc' => __( 'Redirect to checkout immediately after adding the course to the cart.', 'learnpress' ),
1642 + 'id' => $class->get_field_name( 'redirect_after_add' ),
1643 + 'default' => 'yes',
1644 + 'type' => 'checkbox',
1645 + ),
1646 + array(
1647 + 'title' => __( 'AJAX add to cart', 'learnpress' ),
1648 + 'desc' => __( 'Using AJAX to add the course to the cart.', 'learnpress' ),
1649 + 'id' => $class->get_field_name( 'ajax_add_to_cart' ),
1650 + 'default' => 'no',
1651 + 'type' => 'checkbox',
1652 + ),
1653 + array(
1654 + 'title' => __( 'Cart page', 'learnpress' ),
1655 + 'id' => $class->get_field_name( 'cart_page_id' ),
1656 + 'default' => '',
1657 + 'type' => 'pages-dropdown',
1658 + ),
1659 + )
1660 + );
1661 +
1662 + return $settings;
1663 + }
1664 +} else {
1665 + add_filter( 'learn_press_enable_cart', '_learn_press_enable_cart', 1000 );
1666 + function _learn_press_enable_cart( $r ) {
1667 + return false;
1668 + }
1669 +
1670 + add_filter( 'learn_press_get_template', '_learn_press_enroll_button', 1000, 5 );
1671 + function _learn_press_enroll_button( $located, $template_name, $args, $template_path, $default_path ) {
1672 + if ( $template_name == 'single-course/enroll-button.php' ) {
1673 + $located = learn_press_locate_template(
1674 + 'single-course/enroll-button-new.php',
1675 + $template_path,
1676 + $default_path
1677 + );
1678 + }
1679 +
1680 + return $located;
1681 + }
1682 +}
1683 +
1684 +/**
1685 + * Returns checkout url from setting
1686 + *
1687 + * @return string
1688 + */
1689 +function learn_press_get_checkout_url() {
1690 + $checkout_url = learn_press_get_page_link( 'checkout' );
1691 +
1692 + return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
1693 +}
1694 +
1695 +/**
1696 + * @return string
1697 + */
1698 +function learn_press_checkout_needs_payment() {
1699 + return LearnPress::instance()->cart->needs_payment();
1700 +}
1701 +
1702 +/**
1703 + * Return plugin basename
1704 + *
1705 + * @param string $filepath
1706 + *
1707 + * @return string
1708 + */
1709 +/*
1710 +function learn_press_plugin_basename( $filepath ) {
1711 + $file = str_replace( '\\', '/', $filepath );
1712 + $file = preg_replace( '|/+|', '/', $file );
1713 + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR );
1714 + $plugin_dir = preg_replace( '|/+|', '/', $plugin_dir );
1715 + $mu_plugin_dir = str_replace( '\\', '/', WPMU_PLUGIN_DIR );
1716 + $mu_plugin_dir = preg_replace( '|/+|', '/', $mu_plugin_dir );
1717 + $sp_plugin_dir = dirname( $filepath );
1718 + $sp_plugin_dir = dirname( $sp_plugin_dir );
1719 + $sp_plugin_dir = str_replace( '\\', '/', $sp_plugin_dir );
1720 + $sp_plugin_dir = preg_replace( '|/+|', '/', $sp_plugin_dir );
1721 +
1722 + $file = preg_replace(
1723 + '#^' . preg_quote( $sp_plugin_dir, '#' ) . '/|^' . preg_quote(
1724 + $plugin_dir,
1725 + '#'
1726 + ) . '/|^' . preg_quote(
1727 + $mu_plugin_dir,
1728 + '#'
1729 + ) . '/#',
1730 + '',
1731 + $file
1732 + );
1733 + $file = trim( $file, '/' );
1734 +
1735 + return strtolower( $file );
1736 +}*/
1737 +
1738 +/**
1739 + * Update log data for each LP version into wp option.
1740 + *
1741 + * @param string $version
1742 + * @param mixed $data
1743 + */
1744 +function learn_press_update_log( $version, $data ) {
1745 + $logs = get_option( 'learn_press_update_logs' );
1746 + if ( ! $logs ) {
1747 + $logs = array( $version => $data );
1748 + } else {
1749 + $logs[ $version ] = $data;
1750 + }
1751 + update_option( 'learn_press_update_logs', $logs );
1752 +}
1753 +
1754 +/**
1755 + * Output variables to screen for debugging.
1756 + */
1757 +function learn_press_debug() {
1758 + $args = func_get_args();
1759 + $debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
1760 +
1761 + echo '<pre>';
1762 + print_r( $debug );
1763 + $arg = false;
1764 +
1765 + if ( $args ) {
1766 + foreach ( $args as $arg ) {
1767 + echo "\n======LearnPress Debug=======\n";
1768 + print_r( $arg );
1769 + echo "\n=============================\n";
1770 + }
1771 + }
1772 + echo '</pre>';
1773 +
1774 + if ( true === $arg ) {
1775 + die( __FUNCTION__ );
1776 + }
1777 +}
1778 +
1779 +function learn_press_get_requested_post_type() {
1780 + global $pagenow;
1781 + if ( $pagenow == 'post-new.php' && ! empty( $_REQUEST['post_type'] ) ) {
1782 + $post_type = LP_Helper::sanitize_params_submitted( $_REQUEST['post_type'] );
1783 + } else {
1784 + $post_id = learn_press_get_post();
1785 + $post_type = learn_press_get_post_type( $post_id );
1786 + }
1787 +
1788 + return $post_type;
1789 +}
1790 +
1791 +/**
1792 + * Get human string from grade slug.
1793 + *
1794 + * @param string $slug
1795 + *
1796 + * @return string
1797 + */
1798 +function learn_press_get_graduation_text( $slug ) {
1799 + switch ( $slug ) {
1800 + case 'passed':
1801 + $text = esc_html__( 'Passed', 'learnpress' );
1802 + break;
1803 + case 'failed':
1804 + $text = esc_html__( 'Failed', 'learnpress' );
1805 + break;
1806 + case 'in-progress':
1807 + $text = esc_html__( 'In Progress', 'learnpress' );
1808 + break;
1809 + default:
1810 + $text = $slug;
1811 + }
1812 +
1813 + return apply_filters( 'learn-press/get-graduation-text', $text, $slug );
1814 +}
1815 +
1816 +if ( ! function_exists( 'learn_press_is_negative_value' ) ) {
1817 + function learn_press_is_negative_value( $value ) {
1818 + $return = in_array( $value, array( 'no', 'off', 'false', '0' ) ) || ! $value || $value == '' || $value == null;
1819 +
1820 + return $return;
1821 + }
1822 +}
1823 +
1824 +/**
1825 + * Filter to comment reply link to fix bug the link is invalid for
1826 + * lesson or quiz.
1827 + *
1828 + * @param string $link
1829 + * @param array $args
1830 + * @param WP_Comment $comment
1831 + * @param WP_Post $post
1832 + *
1833 + * @return string
1834 + */
1835 +function learn_press_comment_reply_link( $link, $args = array(), $comment = null, $post = null ) {
1836 +
1837 + $post_type = learn_press_get_post_type( $post );
1838 +
1839 + if ( ! learn_press_is_support_course_item_type( $post_type ) ) {
1840 + return $link;
1841 + }
1842 +
1843 + $course_item = LP_Global::course_item();
1844 +
1845 + if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
1846 + $link = sprintf(
1847 + '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
1848 + esc_url_raw( wp_login_url( get_permalink() ) ),
1849 + $args['login_text']
1850 + );
1851 + } elseif ( $course_item ) {
1852 + $onclick = sprintf(
1853 + 'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
1854 + $args['add_below'],
1855 + $comment->comment_ID,
1856 + $args['respond_id'],
1857 + $post->ID
1858 + );
1859 +
1860 + $link = sprintf(
1861 + "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
1862 + esc_url_raw(
1863 + add_query_arg(
1864 + array(
1865 + 'replytocom' => $comment->comment_ID,
1866 + ),
1867 + $course_item->get_permalink()
1868 + )
1869 + ) . '#' . $args['respond_id'],
1870 + $onclick,
1871 + esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
1872 + $args['reply_text']
1873 + );
1874 + }
1875 +
1876 + return $link;
1877 +}
1878 +
1879 +add_filter( 'comment_reply_link', 'learn_press_comment_reply_link', 10, 4 );
1880 +
1881 +/**
1882 + * Sanitize content of tooltip
1883 + *
1884 + * @param string $tooltip
1885 + * @param bool $html
1886 + *
1887 + * @return string
1888 + */
1889 +function learn_press_sanitize_tooltip( $tooltip, $html = false ) {
1890 + if ( $html ) {
1891 + $tooltip = htmlspecialchars(
1892 + wp_kses(
1893 + html_entity_decode( $tooltip ),
1894 + array(
1895 + 'br' => array(),
1896 + 'em' => array(),
1897 + 'strong' => array(),
1898 + 'small' => array(),
1899 + 'span' => array(),
1900 + 'ul' => array(),
1901 + 'li' => array(),
1902 + 'ol' => array(),
1903 + 'p' => array(),
1904 + )
1905 + )
1906 + );
1907 + } else {
1908 + $tooltip = esc_attr( $tooltip );
1909 + }
1910 +
1911 + return $tooltip;
1912 +}
1913 +
1914 +function learn_press_tooltip( $tooltip, $html = false ) {
1915 + $tooltip = learn_press_sanitize_tooltip( $tooltip, $html );
1916 + echo '<span class="learn-press-tooltip" data-tooltip="' . esc_attr( $tooltip ) . '"></span>';
1917 +}
1918 +
1919 +/**
1920 + * Get default static pages of LP.
1921 + *
1922 + * @return array
1923 + *
1924 + * @since 3.0.0
1925 + * @deprecated 4.2.3
1926 + */
1927 +function learn_press_static_page_ids() {
1928 + $pages = LP_Object_Cache::get( 'static-page-ids', 'learn-press' );
1929 +
1930 + if ( false === $pages ) {
1931 + $pages = array(
1932 + 'checkout' => learn_press_get_page_id( 'checkout' ),
1933 + 'courses' => learn_press_get_page_id( 'courses' ),
1934 + 'profile' => learn_press_get_page_id( 'profile' ),
1935 + 'become_a_teacher' => learn_press_get_page_id( 'become_a_teacher' ),
1936 + );
1937 +
1938 + foreach ( $pages as $name => $id ) {
1939 + if ( ! get_post( $id ) ) {
1940 + $pages[ $name ] = 0;
1941 + }
1942 + }
1943 +
1944 + LP_Object_Cache::set( 'static-page-ids', $pages, 'learn-press' );
1945 + }
1946 +
1947 + return apply_filters( 'learn-press/static-page-ids', $pages );
1948 +}
1949 +
1950 +/**
1951 + * Callback function for sorting to array|object by key|prop priority.
1952 + *
1953 + * @param array|object $a
1954 + * @param array|object $b
1955 + *
1956 + * @return int
1957 + * @since 3.0.0
1958 + * @deprecated 4.4.5
1959 + */
1960 +/*function learn_press_sort_list_by_priority_callback( $a, $b ) {
1961 + $a_priority = null;
1962 + $b_priority = null;
1963 +
1964 + if ( is_array( $a ) && array_key_exists( 'priority', $a ) ) {
1965 + $a_priority = $a['priority'];
1966 + } elseif ( is_object( $a ) ) {
1967 + if ( is_callable( array( $a, 'get_priority' ) ) ) {
1968 + $a_priority = $a->get_priority();
1969 + } elseif ( property_exists( $a, 'priority' ) ) {
1970 + $a_priority = $a->priority;
1971 + }
1972 + }
1973 +
1974 + if ( is_array( $b ) && array_key_exists( 'priority', $b ) ) {
1975 + $b_priority = $b['priority'];
1976 + } elseif ( is_object( $b ) ) {
1977 + if ( is_callable( array( $b, 'get_priority' ) ) ) {
1978 + $b_priority = $b->get_priority();
1979 + } elseif ( property_exists( $b, 'priority' ) ) {
1980 + $b_priority = $b->priority;
1981 + }
1982 + }
1983 +
1984 + if ( $a_priority === $b_priority ) {
1985 + return 0;
1986 + }
1987 +
1988 + return ( $a_priority < $b_priority ) ? - 1 : 1;
1989 +}*/
1990 +
1991 +/**
1992 + * Localize date with custom format.
1993 + *
1994 + * @param int|bool $timestamp
1995 + * @param string $format
1996 + * @param bool $gmt
1997 + *
1998 + * @return string
1999 + * @since 3.0.0
2000 + * @deprcated 4.2.6 use LP_Datetime format instead
2001 + */
2002 +function learn_press_date_i18n( $timestamp = 0, string $format = '', bool $gmt = false ): string {
2003 + if ( ! $format ) {
2004 + $format = get_option( 'date_format' );
2005 + }
2006 +
2007 + $date_str = date_i18n( $format, $timestamp, $gmt );
2008 + if ( ! is_string( $date_str ) ) {
2009 + $date_str = '';
2010 + }
2011 +
2012 + return $date_str;
2013 +}
2014 +
2015 +/**
2016 + * Get item types of course support for blocking. Default is lp_lesson
2017 + *
2018 + * @return array
2019 + * @since 3.0.0
2020 + */
2021 +function learn_press_get_block_course_item_types() {
2022 + return apply_filters( 'learn-press/block-course-item-types', array( LP_LESSON_CPT, LP_QUIZ_CPT ) );
2023 +}
2024 +
2025 +/**
2026 + * Get post type of a post from cache.
2027 + * If there is no data stored in cache then
2028 + * get it from WP API.
2029 + *
2030 + * @param int|WP_Post $post
2031 + *
2032 + * @return string
2033 + * @since 3.1.0
2034 + */
2035 +function learn_press_get_post_type( $post ) {
2036 + $post_types = LP_Object_Cache::get( 'post-types', 'learn-press' );
2037 +
2038 + if ( false === $post_types ) {
2039 + $post_types = array();
2040 + }
2041 +
2042 + if ( is_object( $post ) ) {
2043 + $post_id = $post->ID;
2044 + } else {
2045 + $post_id = absint( $post );
2046 + }
2047 +
2048 + if ( empty( $post_types[ $post_id ] ) ) {
2049 + $post_type = get_post_type( $post_id );
2050 + $post_types[ $post_id ] = $post_type;
2051 + LP_Object_Cache::set( 'post-types', $post_types, 'learn-press' );
2052 + } else {
2053 + $post_type = $post_types[ $post_id ];
2054 + }
2055 +
2056 + return $post_type;
2057 +}
2058 +
2059 +/**
2060 + * Update option to enable shuffle themes for ad.
2061 + *
2062 + * @since 3.2.1
2063 + */
2064 +function _learn_press_schedule_enable_shuffle_themes() {
2065 + update_option( 'learn_press_ad_shuffle_themes', 'yes' );
2066 +}
2067 +
2068 +add_action( 'learn-press/schedule-enable-shuffle-themes', '_learn_press_schedule_enable_shuffle_themes' );
2069 +
2070 +/**
2071 + * Return localize script data for admin.
2072 + *
2073 + * @return array
2074 + * @since 3.2.6
2075 + * @version 1.0.1
2076 + */
2077 +function learn_press_global_script_params(): array {
2078 + $localize = [
2079 + 'ajax' => admin_url( 'admin-ajax.php' ),
2080 + 'plugin_url' => LearnPress::instance()->plugin_url(),
2081 + 'siteurl' => home_url(),
2082 + //'current_url' => learn_press_get_current_url(),
2083 + 'theme' => get_stylesheet(),
2084 + 'localize' => array(
2085 + 'button_ok' => __( 'OK', 'learnpress' ),
2086 + 'button_cancel' => __( 'Cancel', 'learnpress' ),
2087 + 'button_yes' => __( 'Yes', 'learnpress' ),
2088 + 'button_no' => __( 'No', 'learnpress' ),
2089 + ),
2090 + 'rest' => esc_url_raw( rest_url() ),
2091 + 'nonce' => wp_create_nonce( 'wp_rest' ),
2092 + 'is_admin' => current_user_can( ADMIN_ROLE ),
2093 + ];
2094 +
2095 + return apply_filters( 'lp/admin/localize/scripts', $localize );
2096 +}
2097 +
2098 +/**
2099 + * Return list types of questions that support answer options.
2100 + *
2101 + * @return array
2102 + * @since 3.3.0
2103 + */
2104 +function learn_press_get_question_support_answer_options() {
2105 + $questions = learn_press_get_question_support_feature( 'answer-options' );
2106 +
2107 + return apply_filters( 'learn-press/questions-support-answer-options', $questions );
2108 +}
2109 +
2110 +/**
2111 + * Return list types of question that support a feature.
2112 + *
2113 + * @param string $feature
2114 + *
2115 + * @return array
2116 + * @since 3.3.0
2117 + */
2118 +function learn_press_get_question_support_feature( $feature ) {
2119 + $questions = array();
2120 + $types = LP_Global::get_object_supports( 'question' );
2121 +
2122 + if ( $types ) {
2123 + foreach ( $types as $type => $features ) {
2124 + if ( array_key_exists( $feature, $features ) ) {
2125 + $questions[] = $type;
2126 + }
2127 + }
2128 + }
2129 +
2130 + return $questions;
2131 +}
2132 +
2133 +/**
2134 + * LP Cookie
2135 + *
2136 + * @param $name
2137 + * @param $namespace
2138 + *
2139 + * @return mixed|null
2140 + */
2141 +function learn_press_cookie_get( $name, $namespace = 'LP' ) {
2142 + if ( $namespace ) {
2143 + $cookie = ! empty( $_COOKIE[ $namespace ] ) ? (array) json_decode( LP_Helper::sanitize_params_submitted( stripslashes( $_COOKIE[ $namespace ] ), 'html' ) ) : array();
2144 + } else {
2145 + $cookie = $_COOKIE;
2146 + }
2147 +
2148 + return $cookie[ $name ] ?? null;
2149 +}
2150 +
2151 +/**
2152 + * Get default methods to evaluate course results.
2153 + *
2154 + * @param string $return - Optional. 'keys' will return keys instead of all.
2155 + *
2156 + * @return array
2157 + * @since 3.x.x
2158 + */
2159 +function learn_press_course_evaluation_methods( $postid, $return = '', $final_quizz_passing = '' ) {
2160 + $final_quiz_btn = sprintf(
2161 + '<a href="#" class="lp-metabox-get-final-quiz" data-postid="%d" data-loading="%s">%s</a>',
2162 + $postid,
2163 + esc_attr__( 'Loading...', 'learnpress' ),
2164 + esc_html__( 'Get A Passing Grade', 'learnpress' )
2165 + );
2166 +
2167 + $evaluations_desc = array(
2168 + 'evaluate_lesson' => sprintf(
2169 + '<p>%s<br/>%s</p>',
2170 + __( 'Evaluate by the number of completed lessons per the total number of lessons.', 'learnpress' ),
2171 + __( 'E.g: If a course has 10 lessons and a user completes 5 lessons, then the result is 5/10 (50%).', 'learnpress' )
2172 + ),
2173 + 'evaluate_final_quiz' => __(
2174 + 'Evaluate by the result of the final quiz in the course. You have to add a quiz at the end of the course.',
2175 + 'learnpress'
2176 + ),
2177 + 'evaluate_quiz' => sprintf(
2178 + '<p>%s<br/>%s</p>',
2179 + __( 'Evaluate by the number of passed quizzes per the total number of quizzes.', 'learnpress' ),
2180 + __(
2181 + 'E.g: If the course has 10 quizzes and the user passes 5 quizzes, then the result is 5/10 (50%).',
2182 + 'learnpress'
2183 + )
2184 + ),
2185 + 'evaluate_questions' => sprintf(
2186 + '<p>%s<br/>%s</p>',
2187 + __( 'Evaluate by the number of correct answers per the total number of questions.', 'learnpress' ),
2188 + __(
2189 + 'E.g: If the course has 10 questions and the user corrects 5 questions, then the result is 5/10 (50%).',
2190 + 'learnpress'
2191 + )
2192 + ),
2193 + 'evaluate_mark' => __( 'Evaluate by the number of achieved scores per the total score of the questions.', 'learnpress' ),
2194 + );
2195 +
2196 + $methods = apply_filters(
2197 + 'learnpress/course-evaluation/methods',
2198 + array(
2199 + 'evaluate_lesson' => sprintf(
2200 + '%s %s',
2201 + __( 'Evaluate via lessons', 'learnpress' ),
2202 + learn_press_quick_tip( $evaluations_desc['evaluate_lesson'], false )
2203 + ),
2204 + 'evaluate_final_quiz' => sprintf(
2205 + '%s %s %s %s',
2206 + __( 'Evaluate via results of the final quiz', 'learnpress' ),
2207 + learn_press_quick_tip( $evaluations_desc['evaluate_final_quiz'], false ),
2208 + $final_quiz_btn,
2209 + $final_quizz_passing
2210 + ),
2211 + 'evaluate_quiz' => sprintf(
2212 + '%s %s',
2213 + __( 'Evaluate via passed quizzes', 'learnpress' ),
2214 + learn_press_quick_tip( $evaluations_desc['evaluate_quiz'], false )
2215 + ),
2216 + 'evaluate_questions' => sprintf(
2217 + '%s %s',
2218 + __( 'Evaluate via questions', 'learnpress' ),
2219 + learn_press_quick_tip( $evaluations_desc['evaluate_questions'], false )
2220 + ),
2221 + 'evaluate_mark' => sprintf(
2222 + '%s %s',
2223 + __( 'Evaluate via mark', 'learnpress' ),
2224 + learn_press_quick_tip( $evaluations_desc['evaluate_mark'], false )
2225 + ),
2226 + ),
2227 + $postid
2228 + );
2229 +
2230 + return apply_filters(
2231 + 'learn-press/course-evaluation-methods',
2232 + $return === 'keys' ? array_keys( $methods ) : $methods,
2233 + $return
2234 + );
2235 +}
2236 +
2237 +/**
2238 + * Get max retrying quiz allowed.
2239 + *
2240 + * @param int $quiz_id
2241 + * @param int $course_id
2242 + *
2243 + * @return int
2244 + * @since 4.0.0
2245 + */
2246 +function learn_press_get_quiz_max_retrying( $quiz_id = 0, $course_id = 0 ) {
2247 + return apply_filters( 'learn-press/max-retry-quiz-allowed', 1, $quiz_id, $course_id );
2248 +}
2249 +
2250 +/**
2251 + * Get slug for status of course/lesson/quiz if user
2252 + * completed/finished and graduation is passed.
2253 + *
2254 + * @param string $type
2255 + *
2256 + * @return string
2257 + * @since 4.0.0
2258 + */
2259 +function learn_press_user_item_in_progress_slug( $type = '' ) {
2260 + return apply_filters( 'learn-press/user-item-in-progress-slug', 'in-progress', $type );
2261 +}
2262 +
2263 +/**
2264 + * Get slug for status of course/lesson/quiz if user
2265 + * completed/finished and result is under-evaluation
2266 + *
2267 + * @param string $item - Optional. Type of item
2268 + *
2269 + * @return string
2270 + * @since 4.0.0
2271 + */
2272 +function learn_press_user_item_under_evaluation_slug( $item = '' ) {
2273 + return apply_filters( 'learn-press/user-item-under-evaluation-slug', 'in-progress', $item );
2274 +}
2275 +
2276 +function learn_press_is_enrolled_slug( $slug ) {
2277 + return in_array(
2278 + $slug,
2279 + array(
2280 + 'in-progress',
2281 + 'enrolled',
2282 + )
2283 + );
2284 +}
2285 +
2286 +/**
2287 + * @return array
2288 + * @since 4.0.0
2289 + */
2290 +function lp_item_course_class( $class = array() ) {
2291 + $classes = array_merge(
2292 + $class,
2293 + array( 'learn-press-courses' )
2294 + );
2295 + echo 'class="' . esc_attr( implode( ' ', apply_filters( 'lp_item_course_class', $classes ) ) ) . '"';
2296 +}
2297 +
2298 +//require_once dirname( __FILE__ ) . '/lp-custom-hooks.php';
2299 +
2300 +// Notify update message for LearnPress plugin
2301 +/*add_action(
2302 + 'in_plugin_update_message-learnpress/learnpress.php',
2303 + function ( $plugin_data ) {
2304 + if ( version_compare( $plugin_data['new_version'], LEARNPRESS_VERSION, '<=' ) ) {
2305 + return;
2306 + }
2307 +
2308 + echo sprintf(
2309 + '<hr/><h3>%s</h3><div>%s</div>',
2310 + esc_html__( 'Heads up! Please backup before upgrading!', 'learnpress' ),
2311 + 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' )
2312 + );
2313 + }
2314 +);*/
2315 +
2316 +/**
2317 + * If Elementor Pro set Theme builder type "Archive", will not show content on page "Archive course"
2318 + *
2319 + * @editor tungnx
2320 + * @author nhamdv
2321 + *
2322 + * @since 4.0.6
2323 + * @version 1.0.1
2324 + */
2325 +add_filter(
2326 + 'elementor/theme/get_location_templates/template_id',
2327 + function ( $theme_template_id ) {
2328 + $elementor_template_type = get_post_meta( $theme_template_id, '_elementor_template_type', true );
2329 +
2330 + if ( in_array( $elementor_template_type, array( 'archive' ) ) ) {
2331 + if ( LP_PAGE_COURSES === LP_Page_Controller::page_current() && class_exists( 'ElementorPro\Modules\ThemeBuilder\Conditions\Archive' ) ) {
2332 + return false;
2333 + }
2334 + }
2335 +
2336 + return $theme_template_id;
2337 + }
2338 +);