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

class-lp-page-controller.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.6.9.2, at inc/class-lp-page-controller.php

1,020 lines 28.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_Page_Controller
5 */
6 class LP_Page_Controller {
7 protected static $_instance = null;
8
9 /**
10 * Store the object has queried by WP.
11 *
12 * @var int
13 */
14 protected $_queried_object = 0;
15
16 /**
17 * @var int
18 */
19 protected $_filter_content_priority = 10000;
20
21 /**
22 * Flag for 404 content.
23 *
24 * @var bool
25 */
26 protected $_is_404 = false;
27
28 /**
29 * LP_Page_Controller constructor.
30 */
31 protected function __construct() {
32 add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
33 add_filter( 'template_include', array( $this, 'template_loader' ), 10 );
34 add_filter( 'template_include', array( $this, 'check_pages' ), 30 );
35 add_filter( 'template_include', array( $this, 'auto_shortcode' ), 50 );
36
37 add_filter( 'the_post', array( $this, 'setup_data_for_item_course' ) );
38 add_filter( 'request', array( $this, 'remove_course_post_format' ), 1 );
39
40 add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
41 add_filter( 'pre_get_document_title', array( $this, 'set_title_pages' ), 20, 1 );
42
43 // Yoast seo
44 add_filter( 'wpseo_opengraph_desc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
45 add_filter( 'wpseo_metadesc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
46
47 // edit link item course when form search default wp
48 add_filter( 'post_type_link', array( $this, 'post_type_link' ), 10, 2 );
49
50 // Set link profile to admin menu
51 add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
52 add_action( 'plugins_loaded', array( $this, 'lp_rest_api_called' ) );
53 }
54
55 /**
56 * Optimize when Rest API LP called
57 *
58 * @return void
59 */
60 public function lp_rest_api_called() {
61 if ( LP_Helper::isRestApiLP() ) {
62 if ( ! defined( 'SHORTINIT' ) ) {
63 define( 'SHORTINIT', true );
64 }
65
66 // Remove hook wp_loaded because query default WP run on it (it hooks 'pre_get_posts',...)
67 remove_all_actions( 'wp_loaded' );
68 }
69 }
70
71 /**
72 * Set link item course when form search default wp
73 *
74 * @param string $post_link
75 * @param object $post
76 */
77 public function post_type_link( $post_link, $post ) {
78 // Set item's course permalink
79 $course_item_types = learn_press_get_course_item_types();
80 $item_id = $post->ID;
81
82 if ( in_array( $post->post_type, $course_item_types ) ) {
83 $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id );
84
85 if ( ! $section_id ) {
86 return $post_link;
87 }
88
89 $course_id = LP_Section_DB::getInstance()->get_course_id_by_section( $section_id );
90
91 if ( ! $course_id ) {
92 return $post_link;
93 }
94
95 $course = learn_press_get_course( $course_id );
96 $post_link = $course->get_item_link( $item_id );
97
98 } elseif ( LP_COURSE_CPT === $post->post_type ) {
99 // Abort early if the placeholder rewrite tag isn't in the generated URL
100 if ( false === strpos( $post_link, '%' ) ) {
101 return $post_link;
102 }
103
104 // Get the custom taxonomy terms in use by this post
105 $terms = get_the_terms( $post->ID, 'course_category' );
106
107 if ( ! empty( $terms ) ) {
108 $terms = _learn_press_usort_terms_by_ID( $terms ); // order by ID
109 $category_object = apply_filters(
110 'learn_press_course_post_type_link_course_category',
111 $terms[0],
112 $terms,
113 $post
114 );
115 $category_object = get_term( $category_object, 'course_category' );
116 $course_category = $category_object->slug;
117
118 $parent = $category_object->parent;
119 if ( $parent ) {
120 $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
121 foreach ( $ancestors as $ancestor ) {
122 $ancestor_object = get_term( $ancestor, 'course_category' );
123 $course_category = $ancestor_object->slug . '/' . $course_category;
124 }
125 }
126 } else {
127 // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
128 $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
129 }
130
131 $find = array(
132 '%year%',
133 '%monthnum%',
134 '%day%',
135 '%hour%',
136 '%minute%',
137 '%second%',
138 '%post_id%',
139 '%category%',
140 '%course_category%',
141 );
142
143 $replace = array(
144 date_i18n( 'Y', strtotime( $post->post_date ) ),
145 date_i18n( 'm', strtotime( $post->post_date ) ),
146 date_i18n( 'd', strtotime( $post->post_date ) ),
147 date_i18n( 'H', strtotime( $post->post_date ) ),
148 date_i18n( 'i', strtotime( $post->post_date ) ),
149 date_i18n( 's', strtotime( $post->post_date ) ),
150 $post->ID,
151 $course_category,
152 $course_category,
153 );
154
155 $post_link = str_replace( $find, $replace, $post_link );
156 }
157
158 return $post_link;
159 }
160
161 private function has_block_template( $template_name ) {
162 if ( ! $template_name ) {
163 return false;
164 }
165
166 $has_template = false;
167 $template_name = str_replace( 'course', LP_COURSE_CPT, $template_name );
168 $template_filename = $template_name . '.html';
169 // Since Gutenberg 12.1.0, the conventions for block templates directories have changed,
170 // we should check both these possible directories for backwards-compatibility.
171 $possible_templates_dirs = array( 'templates', 'block-templates' );
172
173 // Combine the possible root directory names with either the template directory
174 // or the stylesheet directory for child themes, getting all possible block templates
175 // locations combinations.
176 $filepath = DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template_filename;
177 $legacy_filepath = DIRECTORY_SEPARATOR . 'block-templates' . DIRECTORY_SEPARATOR . $template_filename;
178 $possible_paths = array(
179 get_stylesheet_directory() . $filepath,
180 get_stylesheet_directory() . $legacy_filepath,
181 get_template_directory() . $filepath,
182 get_template_directory() . $legacy_filepath,
183 );
184
185 // Check the first matching one.
186 foreach ( $possible_paths as $path ) {
187 if ( is_readable( $path ) ) {
188 $has_template = true;
189 break;
190 }
191 }
192
193 /**
194 * Filters the value of the result of the block template check.
195 *
196 * @since x.x.x
197 *
198 * @param boolean $has_template value to be filtered.
199 * @param string $template_name The name of the template.
200 */
201 return (bool) apply_filters( 'learnpress_has_block_template', $has_template, $template_name );
202 }
203
204 /**
205 * Set title of pages
206 *
207 * 1. Title course archive page
208 * 2. Title item of course
209 * 3. Title page Profile
210 *
211 * @param string $title
212 *
213 * @return string
214 * @author tungnx
215 * @since 3.2.7.7
216 */
217 public function set_title_pages( $title = '' ) {
218 global $wp_query;
219 $flag_title_course = false;
220
221 $course_archive_page_id = LP_Settings::instance()->get( 'courses_page_id', 0 );
222
223 // Set title course archive page
224 if ( ! empty( $course_archive_page_id ) && $wp_query->post &&
225 $course_archive_page_id == $wp_query->post->ID ) {
226 $title = get_the_title( $course_archive_page_id );
227 $flag_title_course = true;
228 } elseif ( learn_press_is_course() ) {
229 $item = LP_Global::course_item();
230 if ( $item ) {
231 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
232
233 $flag_title_course = true;
234 }
235 } elseif ( learn_press_is_courses() ) {
236 if ( learn_press_is_search() ) {
237 $title = __( 'Course Search Results', 'learnpress' );
238 } else {
239 $title = __( 'Courses', 'learnpress' );
240 }
241
242 $flag_title_course = true;
243 } elseif ( learn_press_is_profile() ) {
244 $profile = LP_Profile::instance();
245 $tab_slug = $profile->get_current_tab();
246 $tab = $profile->get_tab_at( $tab_slug );
247
248 if ( $page_id = learn_press_get_page_id( 'profile' ) ) {
249 $page_title = get_the_title( $page_id );
250 } else {
251 $page_title = '';
252 }
253 if ( $tab ) {
254 $title = join(
255 ' ',
256 apply_filters(
257 'learn-press/document-profile-title-parts',
258 array(
259 $page_title,
260 '&rarr;',
261 $tab['title'],
262 )
263 )
264 );
265 }
266
267 $flag_title_course = true;
268 }
269
270 if ( $flag_title_course ) {
271 $title .= ' - ' . get_bloginfo( 'name', 'display' );
272 }
273
274 return apply_filters( 'learn-press/title-page', $title );
275 }
276
277 /**
278 * Set description of course's item for yoast seo
279 *
280 * @param $desc
281 *
282 * @return mixed
283 * @author tungnx
284 * @since 3.2.7.9
285 */
286 public function lp_desc_item_yoast_seo( $desc ) {
287 if ( learn_press_is_course() ) {
288
289 $item = LP_Global::course_item();
290
291 if ( empty( $item ) ) {
292 return $desc;
293 }
294
295 $desc = get_post_meta( $item->get_id(), '_yoast_wpseo_metadesc', true );
296 }
297
298 return $desc;
299 }
300
301 public function check_pages( $template ) {
302 if ( learn_press_is_checkout() ) {
303 $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
304
305 if ( ! $available_gateways ) {
306 learn_press_add_message( __( 'No payment method is available.', 'learnpress' ), 'error' );
307 }
308 } else {
309 global $wp_query;
310
311 $logout_slug = learn_press_profile_logout_slug();
312
313 if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
314 wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
315 exit;
316 }
317 }
318
319 return $template;
320 }
321
322 /**
323 * Auto inserting a registered shortcode to a specific page
324 * if that page is viewing in single mode.
325 *
326 * @param string $template
327 *
328 * @return string;
329 * @since 3.3.0
330 */
331 public function auto_shortcode( $template ) {
332 global $post;
333 $the_post = $post;
334 if ( $the_post && is_page( $the_post->ID ) ) {
335
336 // Filter here to insert the shortcode
337 $auto_shortcodes = apply_filters( 'learn-press/auto-shortcode-pages', array() );
338
339 if ( ! empty( $auto_shortcodes[ $the_post->ID ] ) ) {
340 $shortcode_tag = $auto_shortcodes[ $the_post->ID ];
341
342 preg_match( '/\[' . $shortcode_tag . '\s?(.*)\]/', $the_post->post_content, $results );
343
344 if ( empty( $results ) ) {
345 $content = $the_post->post_content . "[$shortcode_tag]";
346 $the_post->post_content = $content;
347 }
348 }
349 }
350
351 return $template;
352 }
353
354 /**
355 * Load data for item of course
356 *
357 * @param $post
358 *
359 * @return mixed
360 * @editor tungnx
361 * Todo: should remove this function when load true type post's item
362 */
363 public function setup_data_for_item_course( $post ): WP_Post {
364 /**
365 * @var WP $wp
366 * @var WP_Query $wp_query
367 * @var LP_Course $lp_course
368 * @var LP_Course_Item|LP_Quiz|LP_Lesson $lp_course_item
369 */
370 global $wp, $wp_query, $lp_course_item;
371
372 if ( LP_COURSE_CPT !== $post->post_type ) {
373 return $post;
374 }
375
376 $course = learn_press_get_course();
377 if ( ! $course ) {
378 return $post;
379 }
380
381 /**
382 * @deprecated v4.1.6.1 LP()->global['course'], $GLOBALS['course']
383 * Some theme still use: global $course; LP()->global['course']
384 */
385 //LP()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
386 LP()->global['course'] = $GLOBALS['course'] = $course;
387
388 if ( wp_verify_nonce( LP_Request::get( 'preview' ), 'preview-' . $post->ID ) ) {
389 $GLOBALS['preview_course'] = $post->ID;
390 }
391
392 $vars = $wp->query_vars;
393
394 if ( empty( $vars['course-item'] ) ) {
395 return $post;
396 }
397
398 if ( ! $wp_query->is_main_query() ) {
399 return $post;
400 }
401
402 try {
403 $user = learn_press_get_current_user();
404
405 // If item name is set in query vars
406 if ( ! is_numeric( $vars['course-item'] ) ) {
407 $item_type = $vars['item-type'];
408 $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
409 } else {
410 $post_item = get_post( absint( $vars['course-item'] ) );
411 }
412
413 if ( ! $post_item ) {
414 return $post;
415 }
416
417 $lp_course_item = apply_filters( 'learn-press/single-course-request-item', $course->get_item( $post_item->ID ) );
418
419 if ( ! $lp_course_item ) {
420 return $post;
421 }
422
423 // Set item viewing
424 $user->set_viewing_item( $lp_course_item );
425 } catch ( Exception $ex ) {
426 learn_press_add_message( $ex->getMessage(), 'error' );
427 }
428
429 return $post;
430 }
431
432 /**
433 * Set page 404
434 *
435 * @return mixed
436 * @editor tungnx
437 * @reason not use
438 * @deprecated 4.0.0
439 */
440 /*
441 public function set_404( $is_404 ) {
442 global $wp_query;
443 $wp_query->is_404 = $this->_is_404 = (bool) $is_404;
444 }*/
445
446 public function is_404() {
447 return apply_filters( 'learn-press/query/404', $this->_is_404 );
448 }
449
450 /**
451 * In preview mode, if there is a 'post_format' in query var
452 * wp check and replace our post-type to post. This make preview
453 * course item become 404
454 *
455 * @param $qv
456 *
457 * @return mixed
458 */
459 public function remove_course_post_format( $qv ) {
460 if ( ! empty( $qv['post_type'] ) && LP_COURSE_CPT === $qv['post_type'] ) {
461 if ( ! empty( $qv['post_format'] ) ) {
462 unset( $qv['post_format'] );
463 }
464 }
465
466 return $qv;
467 }
468
469 /**
470 * @return bool
471 */
472 protected function _is_archive() {
473 return learn_press_is_courses() || learn_press_is_course_tag() || learn_press_is_course_category() || learn_press_is_search() || learn_press_is_course_tax();
474 }
475
476 /**
477 * @return bool
478 */
479 protected function _is_single() {
480 return learn_press_is_course() && is_single();
481 }
482
483 /**
484 * Load content of course depending on query.
485 *
486 * @param string $template
487 *
488 * @return bool|string
489 */
490 public function template_loader( $template ) {
491
492 if ( is_embed() ) {
493 return $template;
494 }
495
496 // $this->_maybe_redirect_courses_page();
497
498 $default_template = $this->get_page_template();
499
500 if ( $default_template ) {
501 $templates = $this->get_page_templates( $default_template );
502
503 /**
504 * Disable override templates in theme by default since LP 4.0.0
505 */
506 if ( learn_press_override_templates() ) {
507 $new_template = locate_template( $templates );
508 }
509
510 if ( ! isset( $new_template ) || ! $new_template ) {
511 $new_template = LP_TEMPLATE_PATH . $default_template;
512 }
513
514 $template = $new_template;
515 }
516
517 return $template;
518 }
519
520 /**
521 * Get the default filename for a template.
522 *
523 * @return string
524 * @since 4.0.0
525 */
526 private function get_page_template() {
527 $page_template = '';
528
529 if ( is_singular( LP_COURSE_CPT ) ) {
530 if ( ! self::has_block_template( 'single-course' ) ) {
531 $page_template = 'single-course.php';
532 }
533
534 if ( $this->_is_single() ) {
535 global $post;
536 setup_postdata( $post );
537
538 $course_item = LP_Global::course_item();
539 if ( $course_item && ! self::has_block_template( 'content-single-course-item' ) ) {
540 $page_template = 'content-single-item.php';
541 }
542 }
543 } elseif ( learn_press_is_course_taxonomy() ) {
544 $object = get_queried_object();
545
546 if ( is_tax( 'course_category' ) || is_tax( 'course_tag' ) ) {
547 $page_template = 'taxonomy-' . $object->taxonomy . '.php';
548
549 if ( self::has_block_template( 'taxonomy-' . $object->taxonomy ) ) {
550 $page_template = '';
551 } elseif ( ! file_exists( learn_press_locate_template( $page_template ) ) && ! self::has_block_template( 'archive-course' ) ) {
552 $page_template = 'archive-course.php';
553 }
554 } elseif ( ! self::has_block_template( 'archive-course' ) ) {
555 $page_template = 'archive-course.php';
556 }
557 } elseif ( ( is_post_type_archive( LP_COURSE_CPT ) || ( ! empty( learn_press_get_page_id( 'courses' ) ) && is_page( learn_press_get_page_id( 'courses' ) ) ) ) && ! self::has_block_template( 'archive-course' ) ) {
558 $page_template = 'archive-course.php';
559 } elseif ( learn_press_is_checkout() && ! self::has_block_template( 'page-lp_checkout' ) ) {
560 $page_template = 'pages/checkout.php';
561 }
562
563 return apply_filters( 'learn-press/page-template', $page_template );
564 }
565
566 private function get_page_templates( $default_template ) {
567 $templates = apply_filters( 'learn-press/page-templates', array(), $default_template );
568
569 if ( is_page_template() ) {
570 $page_template = get_page_template_slug();
571
572 if ( $page_template ) {
573 $validated_file = validate_file( $page_template );
574 if ( 0 === $validated_file ) {
575 $templates[] = $page_template;
576 } else {
577 error_log( "LearnPress: Unable to validate template path: \"$page_template\". Error Code: $validated_file." );
578 }
579 }
580 }
581
582 if ( is_singular( LP_COURSE_CPT ) ) {
583 $object = get_queried_object();
584 $name_decoded = urldecode( $object->post_name );
585
586 if ( $name_decoded !== $object->post_name ) {
587 $templates[] = "single-course-{$name_decoded}.php";
588 }
589
590 $templates[] = "single-product-{$object->post_name}.php";
591 }
592
593 if ( learn_press_is_course_taxonomy() ) {
594 $object = get_queried_object();
595 $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
596 $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
597 $templates[] = 'taxonomy-' . $object->taxonomy . '.php';
598 $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '.php';
599 }
600
601 $templates[] = $default_template;
602 $templates[] = learn_press_template_path( true ) . $default_template;
603
604 return array_unique( $templates );
605 }
606
607 /**
608 * Filter to allow search more templates in theme for wp page template hierarchy.
609 * Theme twentytwenty used 'singular.php' instead of 'page.php'
610 *
611 * @param array $templates
612 *
613 * @return array
614 * @since 3.x.x
615 * @depecated 4.1.6.9.2
616 */
617 /*public function page_template_hierarchy( $templates ) {
618 $templates = array_merge( $templates, array( 'singular.php' ) );
619
620 return $templates;
621 }*/
622
623 /**
624 * Archive course content.
625 *
626 * @return false|string
627 */
628 public function archive_content() {
629 ob_start();
630 learn_press_get_template( 'content-archive-course.php' );
631
632 return ob_get_clean();
633 }
634
635 /**
636 * @param $title
637 *
638 * @return mixed
639 */
640 public function page_title( $title ) {
641 global $wp_query;
642 if ( ! empty( $wp_query->queried_object_id ) ) {
643 $title['title'] = get_the_title( $wp_query->queried_object_id );
644 }
645
646 return $title;
647 }
648
649 /**
650 * Query courses if page is archive courses
651 *
652 * @param $q WP_Query
653 *
654 * @return WP_Query
655 * @editor tungnx
656 * @modify 4.1.2
657 * @throws Exception
658 */
659 public function pre_get_posts( WP_Query $q ): WP_Query {
660 // Affect only the main query and not in admin
661 if ( ! $q->is_main_query() && ! is_admin() ) {
662 return $q;
663 }
664
665 // Exclude item not assign
666 if ( $q->is_search() ) {
667 // Exclude item not assign any course
668 $course_item_types = learn_press_get_course_item_types();
669 $list_ids_exclude = array();
670
671 foreach ( $course_item_types as $item_type ) {
672 $filter = new LP_Post_Type_Filter();
673 $filter->post_type = $item_type;
674 $exclude_item = LP_Course_DB::getInstance()->get_item_ids_unassigned( $filter );
675 $exclude_item = LP_Course_DB::get_values_by_key( $exclude_item );
676
677 $list_ids_exclude = array_merge( $list_ids_exclude, $exclude_item );
678 }
679
680 // Exclude question not assign any quiz
681 $question_ids = LP_Question_DB::getInstance()->get_questions_not_assign_quiz();
682 $question_ids = LP_Course_DB::get_values_by_key( $question_ids );
683 $list_ids_exclude = array_merge( $list_ids_exclude, $question_ids );
684
685 if ( ! empty( $list_ids_exclude ) ) {
686 $q->set( 'post__not_in', $list_ids_exclude );
687 }
688 }
689
690 $is_archive_course = false;
691
692 // Handle 404 if user are viewing course item directly.
693 $this->set_link_item_course_default_wp_to_page_404( $q );
694
695 $this->_queried_object = ! empty( $q->queried_object_id ) ? $q->queried_object : false;
696
697 /**
698 * If current page is used for courses page
699 * Set on both: "Homepage" and "Posts page" on Reading Settings
700 */
701 $page_courses_id = learn_press_get_page_id( 'courses' );
702
703 if ( $q->is_home() && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) == $page_courses_id ) {
704 $is_archive_course = 1;
705 // $q->is_home = false;
706 // $q->set( 'page_id', get_option( 'page_on_front' ) );
707 }
708
709 /**
710 * If current page is used for courses page and set as "Homepage"
711 */
712 if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $page_courses_id && $q->get( 'page_id' ) == $page_courses_id ) {
713 $is_archive_course = 1;
714
715 /*
716 global $wp_post_types;
717
718 $course_page = get_post( $page_courses_id );
719 $this->_queried_object = $course_page;
720 $wp_post_types[ LP_COURSE_CPT ]->ID = $course_page->ID;
721 $wp_post_types[ LP_COURSE_CPT ]->post_title = $course_page->post_title;
722 $wp_post_types[ LP_COURSE_CPT ]->post_name = $course_page->post_name;
723 $wp_post_types[ LP_COURSE_CPT ]->post_type = $course_page->post_type;
724 $wp_post_types[ LP_COURSE_CPT ]->ancestors = get_ancestors( $course_page->ID, $course_page->post_type );*/
725 }
726
727 // Set custom posts per page
728 if ( $this->_is_archive() ) {
729 $is_archive_course = 1;
730 }
731
732 $apply_lazy_load_for_theme = apply_filters( 'lp/page/courses/query/lazy_load', false );
733
734 if ( $is_archive_course ) {
735 if ( ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses() ) ) {
736 LP()->template( 'course' )->remove_callback( 'learn-press/after-courses-loop', 'loop/course/pagination.php', 10 );
737 /**
738 * If page is archive course - query set posts_per_page = 1
739 * For fastest - because when page loaded - call API to load list courses
740 *
741 * Current, apply only for LP, not apply for theme Thimpress, because theme override
742 */
743 $q->set( 'posts_per_page', 1 );
744 $q->set( 'posts_per_archive_page', 1 );
745 $q->set( 'nopaging', true );
746 } else {
747 $filter = new LP_Course_Filter();
748 $filter->only_fields = [ 'ID' ];
749 $filter->max_limit = $filter->limit = 1000;
750 $is_need_check_in_arr = false;
751 $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
752
753 $q->set( 'posts_per_page', $limit );
754 // $q->set( 'cache_results', true ); // it default true
755
756 // Search courses by keyword
757 // $q->set( 's', $_REQUEST['c_search'] ?? '' );
758 if ( ! empty( $_REQUEST['c_search'] ) ) {
759 $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
760 $is_need_check_in_arr = true;
761 }
762
763 $author_ids_str = LP_Helper::sanitize_params_submitted( $_REQUEST['c_authors'] ?? 0 );
764 if ( ! empty( $author_ids_str ) ) {
765 $q->set( 'author', $author_ids_str );
766 }
767
768 // Meta query
769 $meta_query = [];
770 if ( isset( $_REQUEST['sort_by'] ) ) {
771 $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
772 if ( 'on_paid' === $sort_by ) {
773 $meta_query[] = array(
774 'key' => '_lp_price',
775 'value' => 0,
776 'compare' => '>',
777 );
778 }
779
780 if ( 'on_free' === $sort_by ) {
781 $meta_query[] = array(
782 'key' => '_lp_price',
783 'value' => 0,
784 'compare' => '=',
785 );
786 }
787 }
788 $q->set( 'meta_query', $meta_query );
789 // End Meta query
790
791 // Tax query
792 $tax_query = [];
793 $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['term_id'] ?? '' ) );
794 if ( ! empty( $term_ids_str ) ) {
795 $term_ids = explode( ',', $term_ids_str );
796
797 $tax_query[] = array(
798 'taxonomy' => 'course_category',
799 'field' => 'term_id',
800 'terms' => $term_ids,
801 'operator' => 'IN',
802 );
803 }
804
805 $q->set( 'tax_query', $tax_query );
806 // End Tax query
807
808 // Author query
809 if ( isset( $_REQUEST['c_author'] ) ) {
810 $author_ids = LP_Helper::sanitize_params_submitted( $_REQUEST['c_author'] );
811 $q->set( 'author__in', $author_ids );
812 }
813 // End Author query
814
815 // Order query
816 if ( isset( $_REQUEST['order_by'] ) ) {
817 $order_by = LP_Helper::sanitize_params_submitted( $_REQUEST['order_by'] );
818 $order = 'DESC';
819
820 switch ( $order_by ) {
821 case 'post_title':
822 $order_by = 'title';
823 $order = 'ASC';
824 break;
825 case 'popular':
826 $filter->order_by = 'popular';
827 $order_by = 'post__in';
828 $is_need_check_in_arr = true;
829 break;
830 default:
831 $order_by = 'date';
832 break;
833 }
834
835 $q->set( 'orderby', $order_by );
836 $q->set( 'order', $order );
837 }
838
839 if ( $is_need_check_in_arr ) {
840 $posts_in = LP_Course::get_courses( $filter );
841 if ( ! empty( $posts_in ) ) {
842 $posts_in = LP_Database::get_values_by_key( $posts_in );
843 $q->set( 'post__in', $posts_in );
844 } else {
845 $q->set( 'post__in', 0 );
846 }
847 }
848
849 $q = apply_filters( 'lp/page-courses/query/legacy', $q );
850 }
851 }
852
853 return $q;
854 }
855
856 /**
857 * Handle 404 if user are viewing course item directly.
858 * Example: http://example.com/lesson/slug-lesson
859 * Apply for user not admin, instructor, co-instructor
860 *
861 * @param WP_Query $q
862 *
863 * @return mixed
864 * @editor tungnx
865 * @since 3.2.7.5
866 */
867 public function set_link_item_course_default_wp_to_page_404( $q ) {
868 if ( ! $q->is_main_query() || is_admin() ) {
869 return $q;
870 }
871
872 $post_type_apply_404 = array( LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, 'lp_assignment' );
873
874 if ( isset( $q->query_vars['post_type'] ) && in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
875 $flag_load_404 = true;
876 $user = wp_get_current_user();
877 $post_author = 0;
878
879 if ( $user ) {
880 $post = null;
881
882 if ( isset( $_GET['preview_id'] ) ) {
883 $post_id = absint( $_GET['preview_id'] );
884 $post = get_post( $post_id );
885 $post_author = $post->post_author;
886 } elseif ( isset( $_GET['preview'] ) && isset( $_GET['p'] ) ) {
887 $post_id = absint( $_GET['p'] );
888 $post = get_post( $post_id );
889 $post_author = $post->post_author;
890 } else {
891 $post_author = LP_Database::getInstance()->getPostAuthorByTypeAndSlug( $q->query_vars['post_type'], $q->query_vars[ $q->query_vars['post_type'] ] );
892 }
893
894 if ( $user->has_cap( 'administrator' ) ) {
895 $flag_load_404 = false;
896 } elseif ( $user->has_cap( LP_TEACHER_ROLE ) && $post_author == $user->ID ) {
897 $flag_load_404 = false;
898 }
899 }
900
901 $flag_load_404 = apply_filters( 'learnpress/page/set-link-item-course-404', $flag_load_404, $post_author, $user );
902
903 if ( $flag_load_404 ) {
904 learn_press_404_page();
905 $q->set( 'post_type', '' );
906 }
907 }
908
909 return $q;
910 }
911
912 /**
913 * @depecated 4.1.6.9.2
914 */
915 /*public function the_content_callback( $content ) {
916 if ( $this->_archive_contents ) {
917 preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
918 $this->_shortcode_exists = ! empty( $results );
919 if ( $this->_shortcode_exists ) {
920 $this->_shortcode_tag = $results[0];
921 $content = str_replace( $this->_shortcode_tag, $this->_archive_contents, $content );
922 } else {
923 $content .= $this->_archive_contents;
924 }
925 }
926
927 return $content;
928 }*/
929
930 /**
931 * Check is page Become a teacher
932 *
933 * @return bool|mixed|void
934 * @since 3.2.8
935 * @author tungnx
936 */
937 public static function is_page_become_a_teacher() {
938 $page_id = learn_press_get_page_id( 'become_a_teacher' );
939
940 if ( $page_id && is_page( $page_id ) ) {
941 return true;
942 }
943
944 return apply_filters( 'learnpress/is-page/become-a-teacher', false );
945 }
946
947 /**
948 * Get page current on frontend
949 *
950 * @return string
951 * @since 3.2.8
952 * @author tungnx
953 */
954 public static function page_current(): string {
955 if ( learn_press_is_checkout() ) {
956 return LP_PAGE_CHECKOUT;
957 } elseif ( LP_Global::course_item_quiz() ) {
958 return LP_PAGE_QUIZ;
959 } elseif ( learn_press_is_course() && is_single() && LP_Global::course_item() ) {
960 return LP_PAGE_SINGLE_COURSE_CURRICULUM;
961 } elseif ( learn_press_is_courses() ) {
962 return LP_PAGE_COURSES;
963 } elseif ( learn_press_is_course() ) {
964 return LP_PAGE_SINGLE_COURSE;
965 } elseif ( self::is_page_become_a_teacher() ) {
966 return LP_PAGE_BECOME_A_TEACHER;
967 } elseif ( learn_press_is_profile() ) {
968 return LP_PAGE_PROFILE;
969 } else {
970 return apply_filters( 'learnpress/page/current', '' );
971 }
972 }
973
974 public static function instance() {
975 if ( is_admin() ) {
976 return null;
977 }
978
979 if ( ! self::$_instance ) {
980 self::$_instance = new self();
981 }
982
983 return self::$_instance;
984 }
985
986 /**
987 * Add user profile link into admin bar
988 *
989 * @editor tungnx
990 * @version 1.0.1
991 * @since 3.0.0
992 */
993 public function learn_press_edit_admin_bar() {
994 global $wp_admin_bar;
995
996 $current_user = wp_get_current_user();
997
998 if ( ! in_array( LP_TEACHER_ROLE, $current_user->roles ) && ! in_array( 'administrator', $current_user->roles ) ) {
999 return;
1000 }
1001
1002 $page_profile_id = learn_press_get_page_id( 'profile' );
1003
1004 if ( $page_profile_id && get_post_status( $page_profile_id ) != 'trash' ) {
1005 $user_id = $current_user->ID;
1006
1007 $wp_admin_bar->add_menu(
1008 array(
1009 'id' => 'course_profile',
1010 'parent' => 'user-actions',
1011 'title' => get_the_title( $page_profile_id ),
1012 'href' => learn_press_user_profile_link( $user_id, false ),
1013 )
1014 );
1015 }
1016 }
1017 }
1018
1019 return LP_Page_Controller::instance();
1020