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/class-lp-page-controller.php +800 -726 4.1.6.94.4.8 View file →
@@ -1,14 +1,17 @@
1 1 <?php
2 2
3 +use LearnPress\CourseBuilder\CourseBuilder;
4 +use LearnPress\Helpers\Template;
5 +use LearnPress\Models\CourseModel;
6 +use LearnPress\Models\Courses;
7 +use LearnPress\Models\UserModel;
8 +
3 9 /**
4 10 * Class LP_Page_Controller
5 11 */
6 12 class LP_Page_Controller {
7 - protected static $_instance = null;
8 - protected $_shortcode_exists = false;
9 - protected $_shortcode_tag = '[learn_press_archive_course]';
10 - protected $_archive_contents = null;
13 + protected static $_instance = null;
11 14
12 15 /**
13 16 * Store the object has queried by WP.
14 17 *
@@ -13,14 +16,14 @@
13 16 * Store the object has queried by WP.
14 17 *
15 18 * @var int
16 19 */
17 - protected $_queried_object = 0;
20 + //protected $_queried_object = 0;
18 21
19 22 /**
20 23 * @var int
21 24 */
22 - protected $_filter_content_priority = 10000;
25 + //protected $_filter_content_priority = 10000;
23 26
24 27 /**
25 28 * Flag for 404 content.
26 29 *
@@ -31,83 +34,142 @@
31 34 /**
32 35 * LP_Page_Controller constructor.
33 36 */
34 37 protected function __construct() {
35 - add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
36 - add_filter( 'template_include', array( $this, 'template_loader' ), 10 );
37 - add_filter( 'template_include', array( $this, 'check_pages' ), 30 );
38 - add_filter( 'template_include', array( $this, 'auto_shortcode' ), 50 );
38 + // Set link course, item course.
39 + add_filter( 'post_type_link', array( $this, 'post_type_link' ), 10, 2 );
39 40
40 - add_filter( 'the_post', array( $this, 'setup_data_for_item_course' ) );
41 - add_filter( 'request', array( $this, 'remove_course_post_format' ), 1 );
41 + if ( LP_Page_Controller::is_page_lp_ajax() ) {
42 + if ( ! isset( $_REQUEST['lp-load-ajax'] ) ) {
43 + wp_die( 'Invalid request!', 400 );
44 + }
45 + }
42 46
43 - add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
44 - add_filter( 'pre_get_document_title', array( $this, 'set_title_pages' ), 20, 1 );
47 + if ( is_admin() ) {
48 + add_action( 'admin_init', [ $this, 'redirect_admin_to_course_builder' ] );
49 + } else {
50 + //add_filter( 'post_type_archive_link', [ $this, 'link_archive_course' ], 10, 2 );
51 + add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), - 1 );
52 + // For debug mysql query post of WP.
53 + /*add_filter(
54 + 'posts_request',
55 + function ( $request, $q ) {
56 + LP_Debug::var_dump( $request );
57 + return $request;
58 + },
59 + 10,
60 + 2
61 + );*/
62 + /*add_filter(
63 + 'posts_clauses_request',
64 + function ( $clauses, $wp_query ) {
65 + if ( ! $wp_query->is_search() ) {
66 + return $clauses;
67 + }
45 68
46 - // Yoast seo
47 - add_filter( 'wpseo_opengraph_desc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
48 - add_filter( 'wpseo_metadesc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
69 + $lp_db = LP_Database::getInstance();
70 + $clauses['where'] .= sprintf( " OR ( post_type = '%s' AND meta_key = '_lp_preview' AND meta_value = 'yes')", LP_LESSON_CPT );
71 + $clauses['join'] .= ' INNER JOIN ' . $lp_db->tb_postmeta . ' ON post_id = wp_posts.ID ';
49 72
50 - // edit link item course when form search default wp
51 - add_filter( 'post_type_link', array( $this, 'post_type_link' ), 10, 2 );
52 - // add_action( 'the_post', array( $this, 'learn_press_setup_object_data' ) );
73 + return $clauses;
74 + },
75 + 10,
76 + 2
77 + );*/
78 + // For return result query course to cache.
79 + //add_action( 'posts_pre_query', [ $this, 'posts_pre_query' ], 10, 2 );
80 + add_filter( 'template_include', array( $this, 'template_loader' ), 10 );
81 + add_filter( 'template_include', array( $this, 'logout' ), 30 );
82 + add_action( 'template_redirect', array( $this, 'template_redirect' ), -1 );
53 83
54 - // Set link profile to admin menu
55 - add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
56 - add_action( 'plugins_loaded', array( $this, 'lp_rest_api_called' ) );
57 - }
84 + add_filter( 'the_post', array( $this, 'setup_data_for_item_course' ) );
85 + add_filter( 'request', array( $this, 'remove_course_post_format' ), 1 );
58 86
59 - /**
60 - * Optimize when Rest API LP called
61 - *
62 - * @return void
63 - */
64 - public function lp_rest_api_called() {
65 - if ( LP_Helper::isRestApiLP() ) {
66 - if ( ! defined( 'SHORTINIT' ) ) {
67 - define( 'SHORTINIT', true );
68 - }
87 + //add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
88 + add_filter( 'pre_get_document_title', array( $this, 'set_title_pages' ), 10, 1 );
69 89
70 - // Remove hook wp_loaded because query default WP run on it (it hooks 'pre_get_posts',...)
71 - remove_all_actions( 'wp_loaded' );
72 - }
73 - }
90 + // Yoast seo
91 + add_filter( 'wpseo_opengraph_desc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
92 + add_filter( 'wpseo_metadesc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
74 93
75 - /**
76 - * When the_post is called, put course data into a global.
77 - *
78 - * Todo: after replace code LP::course()
79 - *
80 - * @param mixed $post
81 - *
82 - * @return LP_Course
83 - */
84 - /*public function learn_press_setup_object_data( $post ) {
85 - $object = null;
94 + // Set link profile to admin menu
95 + //add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
86 96
87 - if ( is_int( $post ) ) {
88 - $post = get_post( $post );
97 + // Set again x-wp-nonce on header when has cache with not login.
98 + add_filter( 'rest_send_nocache_headers', array( $this, 'check_x_wp_nonce_cache' ) );
99 +
100 + // Rewrite lesson comment links
101 + add_filter( 'get_comment_link', array( $this, 'edit_lesson_comment_links' ), 10, 2 );
102 + // Active menu
103 + add_filter( 'wp_nav_menu_objects', [ $this, 'menu_active' ], 10, 1 );
104 + // Canonical
105 + add_filter(
106 + 'get_canonical_url',
107 + function ( $canonical_url ) {
108 + if ( LP_Page_Controller::is_page_instructor() ) {
109 + $canonical_url = LP_Helper::getUrlCurrent();
110 + }
111 +
112 + return $canonical_url;
113 + }
114 + );
89 115 }
90 116
91 - if ( ! $post ) {
92 - return $object;
93 - }
117 + // Disable create sitemap for items type of Course.
118 + add_filter(
119 + 'wp_sitemaps_post_types',
120 + function ( $post_types ) {
121 + $item_types = CourseModel::item_types_support();
122 + $item_types[] = LP_QUESTION_CPT;
123 + foreach ( $item_types as $item_type ) {
124 + if ( isset( $post_types[ $item_type ] ) ) {
125 + unset( $post_types[ $item_type ] );
126 + }
127 + }
94 128
95 - if ( LP_COURSE_CPT === $post->post_type ) {
96 - if ( isset( $GLOBALS['course'] ) ) {
97 - unset( $GLOBALS['course'] );
129 + return $post_types;
98 130 }
131 + );
99 132
100 - $object = learn_press_get_course( $post->ID );
133 + /**
134 + * Disable create sitemap for YoastSEO, Rank Math, but can affect to all logic, ex: it makes link edit of items course lose.
135 + *
136 + * @var WP_Post_Type $post_type
137 + */
138 + /*add_filter(
139 + 'is_post_type_viewable',
140 + function ( $is_viewable, $post_type ) {
141 + $item_types = CourseModel::item_types_support();
142 + $item_types[] = LP_QUESTION_CPT;
143 + if ( in_array( $post_type->name, $item_types ) ) {
144 + $is_viewable = false;
145 + }
101 146
102 - LP()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $object;
147 + return $is_viewable;
148 + },
149 + 10,
150 + 2
151 + );*/
152 + }
153 +
154 + /**
155 + * Set link archive course.
156 + *
157 + * @param string $link
158 + * @param string $post_type
159 + *
160 + * @return string
161 + */
162 + public function link_archive_course( string $link, string $post_type ): string {
163 + if ( $post_type == LP_COURSE_CPT && learn_press_get_page_id( 'courses' ) ) {
164 + $link = learn_press_get_page_link( 'courses' );
103 165 }
104 166
105 - return $object;
106 - }*/
167 + return $link;
168 + }
107 169
108 170 /**
109 - * Set link item course when form search default wp
171 + * Set link course, item course
110 172 *
111 173 * @param string $post_link
112 174 * @param object $post
113 175 */
@@ -112,133 +174,37 @@
112 174 * @param object $post
113 175 */
114 176 public function post_type_link( $post_link, $post ) {
115 177 // Set item's course permalink
116 - $course_item_types = learn_press_get_course_item_types();
178 + $course_item_types = CourseModel::item_types_support();
117 179 $item_id = $post->ID;
118 180
119 - if ( in_array( $post->post_type, $course_item_types ) ) {
181 + // Link item course on search page of WP.
182 + if ( in_array( $post->post_type, $course_item_types ) && is_search() ) {
120 183 $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id );
121 -
122 184 if ( ! $section_id ) {
123 185 return $post_link;
124 186 }
125 187
126 188 $course_id = LP_Section_DB::getInstance()->get_course_id_by_section( $section_id );
127 -
128 189 if ( ! $course_id ) {
129 190 return $post_link;
130 191 }
131 192
132 - $course = learn_press_get_course( $course_id );
133 - $post_link = $course->get_item_link( $item_id );
134 -
135 - } elseif ( LP_COURSE_CPT === $post->post_type ) {
136 - // Abort early if the placeholder rewrite tag isn't in the generated URL
137 - if ( false === strpos( $post_link, '%' ) ) {
193 + $course = learn_press_get_course( $course_id );
194 + if ( ! $course ) {
138 195 return $post_link;
139 196 }
140 197
141 - // Get the custom taxonomy terms in use by this post
142 - $terms = get_the_terms( $post->ID, 'course_category' );
143 -
144 - if ( ! empty( $terms ) ) {
145 - $terms = _learn_press_usort_terms_by_ID( $terms ); // order by ID
146 - $category_object = apply_filters(
147 - 'learn_press_course_post_type_link_course_category',
148 - $terms[0],
149 - $terms,
150 - $post
151 - );
152 - $category_object = get_term( $category_object, 'course_category' );
153 - $course_category = $category_object->slug;
154 -
155 - $parent = $category_object->parent;
156 - if ( $parent ) {
157 - $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
158 - foreach ( $ancestors as $ancestor ) {
159 - $ancestor_object = get_term( $ancestor, 'course_category' );
160 - $course_category = $ancestor_object->slug . '/' . $course_category;
161 - }
162 - }
163 - } else {
164 - // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
165 - $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
166 - }
167 -
168 - $find = array(
169 - '%year%',
170 - '%monthnum%',
171 - '%day%',
172 - '%hour%',
173 - '%minute%',
174 - '%second%',
175 - '%post_id%',
176 - '%category%',
177 - '%course_category%',
178 - );
179 -
180 - $replace = array(
181 - date_i18n( 'Y', strtotime( $post->post_date ) ),
182 - date_i18n( 'm', strtotime( $post->post_date ) ),
183 - date_i18n( 'd', strtotime( $post->post_date ) ),
184 - date_i18n( 'H', strtotime( $post->post_date ) ),
185 - date_i18n( 'i', strtotime( $post->post_date ) ),
186 - date_i18n( 's', strtotime( $post->post_date ) ),
187 - $post->ID,
188 - $course_category,
189 - $course_category,
190 - );
191 -
192 - $post_link = str_replace( $find, $replace, $post_link );
198 + $post_link = $course->get_item_link( $item_id );
199 + } elseif ( LP_COURSE_CPT === $post->post_type ) {
200 + // Link single course (with %course_category%).
201 + $post_link = LP_Helper::handle_lp_permalink_structure( $post_link, $post );
193 202 }
194 203
195 204 return $post_link;
196 205 }
197 206
198 - private function has_block_template( $template_name ) {
199 - if ( ! $template_name ) {
200 - return false;
201 - }
202 -
203 - $has_template = false;
204 - $template_name = str_replace( 'course', LP_COURSE_CPT, $template_name );
205 - $template_filename = $template_name . '.html';
206 - // Since Gutenberg 12.1.0, the conventions for block templates directories have changed,
207 - // we should check both these possible directories for backwards-compatibility.
208 - $possible_templates_dirs = array( 'templates', 'block-templates' );
209 -
210 - // Combine the possible root directory names with either the template directory
211 - // or the stylesheet directory for child themes, getting all possible block templates
212 - // locations combinations.
213 - $filepath = DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template_filename;
214 - $legacy_filepath = DIRECTORY_SEPARATOR . 'block-templates' . DIRECTORY_SEPARATOR . $template_filename;
215 - $possible_paths = array(
216 - get_stylesheet_directory() . $filepath,
217 - get_stylesheet_directory() . $legacy_filepath,
218 - get_template_directory() . $filepath,
219 - get_template_directory() . $legacy_filepath,
220 - );
221 -
222 - // Check the first matching one.
223 - foreach ( $possible_paths as $path ) {
224 - if ( is_readable( $path ) ) {
225 - $has_template = true;
226 - break;
227 - }
228 - }
229 -
230 - /**
231 - * Filters the value of the result of the block template check.
232 - *
233 - * @since x.x.x
234 - *
235 - * @param boolean $has_template value to be filtered.
236 - * @param string $template_name The name of the template.
237 - */
238 - return (bool) apply_filters( 'learnpress_has_block_template', $has_template, $template_name );
239 - }
240 -
241 207 /**
242 208 * Set title of pages
243 209 *
244 210 * 1. Title course archive page
@@ -247,23 +213,21 @@
247 213 *
248 214 * @param string $title
249 215 *
250 216 * @return string
217 + * @throws Exception
218 + * @since 3.2.7.7
219 + * @version 1.0.2
251 220 * @author tungnx
252 - * @since 3.2.7.7
253 221 */
254 - public function set_title_pages( $title = '' ) {
255 - global $wp_query;
222 + public function set_title_pages( $title = '' ): string {
256 223 $flag_title_course = false;
224 + $user_id = get_current_user_id();
257 225
258 - $course_archive_page_id = LP_Settings::instance()->get( 'courses_page_id', 0 );
226 + $course_archive_page_id = LP_Settings::get_option( 'courses_page_id', 0 );
259 227
260 - // Set title course archive page
261 - if ( ! empty( $course_archive_page_id ) && $wp_query->post &&
262 - $course_archive_page_id == $wp_query->post->ID ) {
263 - $title = get_the_title( $course_archive_page_id );
264 - $flag_title_course = true;
265 - } elseif ( learn_press_is_course() ) {
228 + // Set title single course.
229 + if ( learn_press_is_course() ) {
266 230 $item = LP_Global::course_item();
267 231 if ( $item ) {
268 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
269 233
@@ -268,27 +232,41 @@
268 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
269 233
270 234 $flag_title_course = true;
271 235 }
272 - } elseif ( learn_press_is_courses() ) {
273 - if ( learn_press_is_search() ) {
236 + } elseif ( LP_Page_Controller::is_page_courses() ) { // Set title course archive page.
237 + if ( isset( $_GET['c_search'] ) ) {
274 238 $title = __( 'Course Search Results', 'learnpress' );
239 + } elseif ( is_tax( LP_COURSE_CATEGORY_TAX ) || is_tax( LP_COURSE_TAXONOMY_TAG ) ) {
240 + /**
241 + * @var WP_Query $wp_query
242 + */
243 + global $wp_query;
244 + if ( $wp_query->queried_object ) {
245 + $title = $wp_query->queried_object->name;
246 + }
275 247 } else {
276 - $title = __( 'Courses', 'learnpress' );
248 + $title = $course_archive_page_id ? get_the_title( $course_archive_page_id ) : __( 'Courses', 'learnpress' );
277 249 }
278 250
279 251 $flag_title_course = true;
280 - } elseif ( learn_press_is_profile() ) {
281 - $profile = LP_Profile::instance();
282 - $tab_slug = $profile->get_current_tab();
283 - $tab = $profile->get_tab_at( $tab_slug );
252 + } elseif ( LP_Page_Controller::is_page_profile() ) {
253 + $userModel = UserModel::find( get_current_user_id(), true );
254 + $profile = LP_Profile::instance( $user_id );
255 + $page_id = learn_press_get_page_id( 'profile' );
256 + $tab = false;
257 + if ( $userModel ) {
258 + $tab_slug = $profile->get_current_tab();
259 + $tab = $profile->get_tab_at( $tab_slug );
260 + }
284 261
285 - if ( $page_id = learn_press_get_page_id( 'profile' ) ) {
262 + if ( $page_id ) {
286 263 $page_title = get_the_title( $page_id );
287 264 } else {
288 265 $page_title = '';
289 266 }
290 - if ( $tab ) {
267 +
268 + if ( $tab instanceof LP_Profile_Tab ) {
291 269 $title = join(
292 270 ' ',
293 271 apply_filters(
294 272 'learn-press/document-profile-title-parts',
@@ -294,12 +272,14 @@
294 272 'learn-press/document-profile-title-parts',
295 273 array(
296 274 $page_title,
297 275 '&rarr;',
298 - $tab['title'],
276 + $tab->get( 'title' ),
299 277 )
300 278 )
301 279 );
280 + } else {
281 + $title = $page_title;
302 282 }
303 283
304 284 $flag_title_course = true;
305 285 }
@@ -307,8 +287,12 @@
307 287 if ( $flag_title_course ) {
308 288 $title .= ' - ' . get_bloginfo( 'name', 'display' );
309 289 }
310 290
291 + if ( ! is_string( $title ) ) {
292 + $title = get_bloginfo( 'name', 'display' );
293 + }
294 +
311 295 return apply_filters( 'learn-press/title-page', $title );
312 296 }
313 297
314 298 /**
@@ -334,56 +318,19 @@
334 318
335 319 return $desc;
336 320 }
337 321
338 - public function check_pages( $template ) {
339 - if ( learn_press_is_checkout() ) {
340 - $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
341 -
342 - if ( ! $available_gateways ) {
343 - learn_press_add_message( __( 'No payment method is available.', 'learnpress' ), 'error' );
344 - }
345 - } else {
346 - global $wp_query;
347 -
348 - $logout_slug = learn_press_profile_logout_slug();
349 -
350 - if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
351 - wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
352 - exit;
353 - }
354 - }
355 -
356 - return $template;
357 - }
358 -
359 322 /**
360 - * Auto inserting a registered shortcode to a specific page
361 - * if that page is viewing in single mode.
362 - *
363 - * @param string $template
364 - *
365 - * @return string;
366 - * @since 3.3.0
323 + * Handle logout
367 324 */
368 - public function auto_shortcode( $template ) {
369 - global $post;
370 - $the_post = $post;
371 - if ( $the_post && is_page( $the_post->ID ) ) {
325 + public function logout( $template ) {
326 + global $wp_query;
372 327
373 - // Filter here to insert the shortcode
374 - $auto_shortcodes = apply_filters( 'learn-press/auto-shortcode-pages', array() );
328 + $logout_slug = learn_press_profile_logout_slug();
375 329
376 - if ( ! empty( $auto_shortcodes[ $the_post->ID ] ) ) {
377 - $shortcode_tag = $auto_shortcodes[ $the_post->ID ];
378 -
379 - preg_match( '/\[' . $shortcode_tag . '\s?(.*)\]/', $the_post->post_content, $results );
380 -
381 - if ( empty( $results ) ) {
382 - $content = $the_post->post_content . "[$shortcode_tag]";
383 - $the_post->post_content = $content;
384 - }
385 - }
330 + if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
331 + wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
332 + exit;
386 333 }
387 334
388 335 return $template;
389 336 }
@@ -404,8 +351,12 @@
404 351 * @var LP_Course $lp_course
405 352 * @var LP_Course_Item|LP_Quiz|LP_Lesson $lp_course_item
406 353 */
407 354 global $wp, $wp_query, $lp_course_item;
355 + $vars = $wp->query_vars;
356 + if ( empty( $vars['course-item'] ) ) {
357 + return $post;
358 + }
408 359
409 360 if ( LP_COURSE_CPT !== $post->post_type ) {
410 361 return $post;
411 362 }
@@ -415,24 +366,30 @@
415 366 return $post;
416 367 }
417 368
418 369 /**
419 - * @deprecated v4.1.6.1 LP()->global['course'], $GLOBALS['course']
420 - * Some theme still use: global $course; LP()->global['course']
370 + * Use for case not load course via send params, use global instead.
371 + * Not recommended for use
372 + * This method is only purpose instead get_the_ID(), on file item of course.
373 + * When all file write by standard callback send param courseModel, this method will be removed.
374 + *
375 + * @return false|CourseModel
376 + * @since 4.2.7.4
421 377 */
422 - //LP()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
423 - LP()->global['course'] = $GLOBALS['course'] = $course;
378 + global $lpCourseModel;
379 + $lpCourseModel = CourseModel::find( $course->get_id(), true );
424 380
425 - if ( wp_verify_nonce( LP_Request::get( 'preview' ), 'preview-' . $post->ID ) ) {
381 + /**
382 + * @deprecated v4.1.6.1 LearnPress::instance()->global['course'], $GLOBALS['course']
383 + * Some theme still use: global $course; LearnPress::instance()->global['course']
384 + */
385 + //LearnPress::instance()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
386 + LearnPress::instance()->global['course'] = $GLOBALS['course'] = $course;
387 +
388 + if ( wp_verify_nonce( LP_Request::get_param( 'preview' ), 'preview-' . $post->ID ) ) {
426 389 $GLOBALS['preview_course'] = $post->ID;
427 390 }
428 391
429 - $vars = $wp->query_vars;
430 -
431 - if ( empty( $vars['course-item'] ) ) {
432 - return $post;
433 - }
434 -
435 392 if ( ! $wp_query->is_main_query() ) {
436 393 return $post;
437 394 }
438 395
@@ -439,14 +396,10 @@
439 396 try {
440 397 $user = learn_press_get_current_user();
441 398
442 399 // If item name is set in query vars
443 - if ( ! is_numeric( $vars['course-item'] ) ) {
444 - $item_type = $vars['item-type'];
445 - $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
446 - } else {
447 - $post_item = get_post( absint( $vars['course-item'] ) );
448 - }
400 + $item_type = $vars['item-type'];
401 + $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
449 402
450 403 if ( ! $post_item ) {
451 404 return $post;
452 405 }
@@ -458,29 +411,15 @@
458 411 }
459 412
460 413 // Set item viewing
461 414 $user->set_viewing_item( $lp_course_item );
462 - } catch ( Exception $ex ) {
463 - learn_press_add_message( $ex->getMessage(), 'error' );
415 + } catch ( Throwable $e ) {
416 + error_log( $e->getMessage() );
464 417 }
465 418
466 419 return $post;
467 420 }
468 421
469 - /**
470 - * Set page 404
471 - *
472 - * @return mixed
473 - * @editor tungnx
474 - * @reason not use
475 - * @deprecated 4.0.0
476 - */
477 - /*
478 - public function set_404( $is_404 ) {
479 - global $wp_query;
480 - $wp_query->is_404 = $this->_is_404 = (bool) $is_404;
481 - }*/
482 -
483 422 public function is_404() {
484 423 return apply_filters( 'learn-press/query/404', $this->_is_404 );
485 424 }
486 425
@@ -504,17 +443,23 @@
504 443 }
505 444
506 445 /**
507 446 * @return bool
447 + * @deprecated v4.2.7.6
508 448 */
509 449 protected function _is_archive() {
450 + _deprecated_function( __METHOD__, '4.1.7.3' );
451 + return false;
510 452 return learn_press_is_courses() || learn_press_is_course_tag() || learn_press_is_course_category() || learn_press_is_search() || learn_press_is_course_tax();
511 453 }
512 454
513 455 /**
514 456 * @return bool
457 + * @deprecated v4.2.7.6
515 458 */
516 459 protected function _is_single() {
460 + _deprecated_function( __METHOD__, '4.1.7.3' );
461 + return false;
517 462 return learn_press_is_course() && is_single();
518 463 }
519 464
520 465 /**
@@ -524,8 +469,11 @@
524 469 *
525 470 * @return bool|string
526 471 */
527 472 public function template_loader( $template ) {
473 + if ( wp_is_block_theme() ) {
474 + return $template;
475 + }
528 476
529 477 if ( is_embed() ) {
530 478 return $template;
531 479 }
@@ -554,8 +502,18 @@
554 502 return $template;
555 503 }
556 504
557 505 /**
506 + * Check if current page is Course Builder
507 + */
508 + public function template_redirect() {
509 + if ( LP_Page_Controller::is_page_course_builder() ) {
510 + include LP_TEMPLATE_PATH . 'pages/course-builder.php';
511 + die;
512 + }
513 + }
514 +
515 + /**
558 516 * Get the default filename for a template.
559 517 *
560 518 * @return string
561 519 * @since 4.0.0
@@ -561,40 +519,59 @@
561 519 * @since 4.0.0
562 520 */
563 521 private function get_page_template() {
564 522 $page_template = '';
523 + $object = get_queried_object();
565 524
566 - if ( is_singular( LP_COURSE_CPT ) ) {
567 - if ( ! self::has_block_template( 'single-course' ) ) {
525 + if ( self::is_page_single_course() ) {
526 + $page_template = 'single-course-layout.php';
527 + // Check condition to load single course layout classic or modern.
528 + $is_override_single_course = Template::check_template_is_override( 'single-course.php' )
529 + || Template::check_template_is_override( 'content-course.php' )
530 + || Template::check_template_is_override( 'content-single-course.php' )
531 + || Template::check_template_is_override( 'loop/single-course/loop-section.php' )
532 + || Template::check_template_is_override( 'single-course/loop-section.php' )
533 + || Template::check_template_is_override( 'single-course/tabs/curriculum.php' )
534 + || Template::check_template_is_override( 'single-course/tabs/curriculum-v2.php' );
535 + $option_single_course_layout = LP_Settings::get_option( 'layout_single_course', '' );
536 +
537 + if ( $is_override_single_course ) { // Old file template
568 538 $page_template = 'single-course.php';
539 + } elseif ( empty( $option_single_course_layout )
540 + || $option_single_course_layout === 'classic' ) {
541 + $page_template = 'single-course-layout-classic.php';
542 + // Set temporary old single course layout.
543 + $page_template = 'single-course.php';
569 544 }
570 545
571 - if ( $this->_is_single() ) {
572 - global $post;
573 - setup_postdata( $post );
546 + // Old single course layout.
547 + //$page_template = 'single-course.php';
574 548
575 - $course_item = LP_Global::course_item();
576 - if ( $course_item && ! self::has_block_template( 'content-single-course-item' ) ) {
577 - $page_template = 'content-single-item.php';
549 + global $post;
550 + setup_postdata( $post );
551 +
552 + $course_item = LP_Global::course_item();
553 + if ( $course_item ) {
554 + $page_template = 'content-single-item.php';
555 + } elseif ( $object ) {
556 + $course = CourseModel::find( $object->ID, true );
557 + if ( $course && $course->is_offline() ) {
558 + $page_template = 'single-course-offline.php';
578 559 }
579 560 }
580 561 } elseif ( learn_press_is_course_taxonomy() ) {
581 - $object = get_queried_object();
582 -
583 562 if ( is_tax( 'course_category' ) || is_tax( 'course_tag' ) ) {
584 563 $page_template = 'taxonomy-' . $object->taxonomy . '.php';
585 564
586 - if ( self::has_block_template( 'taxonomy-' . $object->taxonomy ) ) {
587 - $page_template = '';
588 - } elseif ( ! file_exists( learn_press_locate_template( $page_template ) ) && ! self::has_block_template( 'archive-course' ) ) {
565 + if ( ! file_exists( learn_press_locate_template( $page_template ) ) ) {
589 566 $page_template = 'archive-course.php';
590 567 }
591 - } elseif ( ! self::has_block_template( 'archive-course' ) ) {
568 + } else {
592 569 $page_template = 'archive-course.php';
593 570 }
594 - } 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' ) ) {
571 + } elseif ( self::is_page_courses() ) {
595 572 $page_template = 'archive-course.php';
596 - } elseif ( learn_press_is_checkout() && ! self::has_block_template( 'page-lp_checkout' ) ) {
573 + } elseif ( learn_press_is_checkout() ) {
597 574 $page_template = 'pages/checkout.php';
598 575 }
599 576
600 577 return apply_filters( 'learn-press/page-template', $page_template );
@@ -615,104 +592,34 @@
615 592 }
616 593 }
617 594 }
618 595
619 - if ( is_singular( LP_COURSE_CPT ) ) {
596 + /*if ( is_singular( LP_COURSE_CPT ) ) {
620 597 $object = get_queried_object();
621 598 $name_decoded = urldecode( $object->post_name );
622 599
623 600 if ( $name_decoded !== $object->post_name ) {
624 - $templates[] = "single-course-{$name_decoded}.php";
601 + $templates[] = "single-course-$name_decoded.php";
625 602 }
626 603
627 - $templates[] = "single-product-{$object->post_name}.php";
628 - }
604 + $templates[] = "single-product-$object->post_name.php";
605 + }*/
629 606
630 607 if ( learn_press_is_course_taxonomy() ) {
631 608 $object = get_queried_object();
632 609 $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
633 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
610 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
634 611 $templates[] = 'taxonomy-' . $object->taxonomy . '.php';
635 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '.php';
612 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '.php';
636 613 }
637 614
638 615 $templates[] = $default_template;
639 - $templates[] = learn_press_template_path( true ) . $default_template;
616 + $templates[] = learn_press_template_path() . '/' . $default_template;
640 617
641 618 return array_unique( $templates );
642 619 }
643 620
644 621 /**
645 - * Filter to allow search more templates in theme for wp page template hierarchy.
646 - * Theme twentytwenty used 'singular.php' instead of 'page.php'
647 - *
648 - * @param array $templates
649 - *
650 - * @return array
651 - * @since 3.x.x
652 - */
653 - public function page_template_hierarchy( $templates ) {
654 - $templates = array_merge( $templates, array( 'singular.php' ) );
655 -
656 - return $templates;
657 - }
658 -
659 - /**
660 - * @return bool
661 - * @editor tungnx - comment 4.1.6.6
662 - */
663 - // protected function _maybe_redirect_courses_page() {
664 - // /**
665 - // * If is archive course page and a static page is used for displaying courses
666 - // * we need to redirect it to the right page
667 - // */
668 - // if ( ! is_post_type_archive( LP_COURSE_CPT ) ) {
669 - // return false;
670 - // }
671 - //
672 - // /**
673 - // * @var WP_Query $wp_query
674 - // * @var WP_Rewrite $wp_rewrite
675 - // */
676 - // global $wp_query, $wp_rewrite;
677 - //
678 - // $page_id = learn_press_get_page_id( 'courses' );
679 - //
680 - // if ( $page_id && ( empty( $wp_query->queried_object_id ) || ! empty( $wp_query->queried_object_id ) && $page_id != $wp_query->queried_object_id ) ) {
681 - // $redirect = trailingslashit( learn_press_get_page_link( 'courses' ) );
682 - //
683 - // if ( ! empty( $wp_query->query['paged'] ) ) {
684 - // if ( $wp_rewrite->using_permalinks() ) {
685 - // $redirect = $redirect . 'page/' . $wp_query->query['paged'] . '/';
686 - // } else {
687 - // $redirect = add_query_arg( 'paged', $wp_query->query['paged'], $redirect );
688 - // }
689 - // }
690 - //
691 - // if ( isset( $_GET ) ) {
692 - // $_GET = array_map( 'stripslashes_deep', $_GET );
693 - // foreach ( $_GET as $k => $v ) {
694 - // $redirect = add_query_arg( $k, urlencode( $v ), $redirect );
695 - // }
696 - // }
697 - //
698 - // if ( $page_id != get_option( 'page_on_front' ) && ! learn_press_is_current_url( $redirect ) ) {
699 - // wp_redirect( $redirect );
700 - // exit();
701 - // }
702 - // }
703 - //
704 - // return false;
705 - // }
706 -
707 - public function archive_content() {
708 - ob_start();
709 - learn_press_get_template( 'content-archive-course.php' );
710 -
711 - return ob_get_clean();
712 - }
713 -
714 - /**
715 622 * @param $title
716 623 *
717 624 * @return mixed
718 625 */
@@ -725,164 +632,8 @@
725 632 return $title;
726 633 }
727 634
728 635 /**
729 - * Load archive courses content.
730 - *
731 - * @param string $template
732 - *
733 - * @return string
734 - */
735 - public function _load_archive_courses( $template ) {
736 -
737 - if ( ! defined( 'LEARNPRESS_IS_COURSES' ) ) {
738 - define( 'LEARNPRESS_IS_COURSES', learn_press_is_courses() );
739 - }
740 -
741 - if ( ! defined( 'LEARNPRESS_IS_TAG' ) ) {
742 - define( 'LEARNPRESS_IS_TAG', learn_press_is_course_tag() );
743 - }
744 -
745 - if ( ! defined( 'LEARNPRESS_IS_CATEGORY' ) ) {
746 - define( 'LEARNPRESS_IS_CATEGORY', learn_press_is_course_category() );
747 - }
748 -
749 - if ( ! defined( 'LEARNPRESS_IS_TAX' ) ) {
750 - define( 'LEARNPRESS_IS_TAX', learn_press_is_course_tax() );
751 - }
752 -
753 - if ( ! defined( 'LEARNPRESS_IS_SEARCH' ) ) {
754 - define( 'LEARNPRESS_IS_SEARCH', learn_press_is_search() );
755 - }
756 -
757 - if ( LEARNPRESS_IS_COURSES || LEARNPRESS_IS_TAG || LEARNPRESS_IS_CATEGORY || LEARNPRESS_IS_SEARCH || LEARNPRESS_IS_TAX ) {
758 - global $wp_query;
759 - // PHP 7
760 - LP()->wp_query = clone $wp_query;
761 -
762 - $template = get_page_template();
763 -
764 - /**
765 - * Fix in case a static page is used for archive course page and
766 - * it's slug is the same with course archive slug (courses).
767 - * In this case, WP know it as a course archive page not a
768 - * single page.
769 - */
770 - $course_page_id = learn_press_get_page_id( 'courses' );
771 - $course_page_slug = get_post_field( 'post_name', $course_page_id );
772 - if ( ! LEARNPRESS_IS_CATEGORY && $course_page_id && $course_page_slug ) {
773 - if ( $course_page_slug == 'courses' ) {
774 - $wp_query->queried_object_id = $course_page_id;
775 - $this->queried_object = $wp_query->queried_object = get_post( $course_page_id );
776 - add_filter( 'document_title_parts', array( $this, 'page_title' ) );
777 - }
778 - }
779 -
780 - $wp_query->posts_per_page = 1;
781 - $wp_query->nopaging = true;
782 - $wp_query->post_count = 1;
783 -
784 - // If we don't have a post, load an empty one
785 - if ( ! empty( $this->_queried_object ) ) {
786 - $wp_query->post = $this->_queried_object;
787 - } elseif ( empty( $wp_query->post ) || learn_press_is_courses() /* -> Fixed: archive course page displays name of first course */ ) {
788 - $wp_query->post = new WP_Post( new stdClass() );
789 - } elseif ( $wp_query->post->post_type != 'page' ) {
790 - // Do not show content of post if it is not a page
791 - $wp_query->post->post_content = '';
792 - }
793 - $content = $wp_query->post->post_content;
794 -
795 - preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
796 - $this->_shortcode_exists = ! empty( $results );
797 -
798 - if ( empty( $results ) ) {
799 - $content = wpautop( $content ) . $this->_shortcode_tag;
800 - } else {
801 - $this->_shortcode_tag = $results[0];
802 - }
803 -
804 - $has_filter = false;
805 - if ( has_filter( 'the_content', 'wpautop' ) ) {
806 - $has_filter = true;
807 - remove_filter( 'the_content', 'wpautop' );
808 - }
809 -
810 - // $content = do_shortcode( $content );
811 -
812 - if ( $has_filter ) {
813 - // add_filter( 'the_content', 'wpautop' );
814 - }
815 -
816 - $this->_archive_contents = do_shortcode( $this->_shortcode_tag );
817 - if ( class_exists( 'SiteOrigin_Panels' ) ) {
818 - if ( class_exists( 'SiteOrigin_Panels' ) &&
819 - has_filter( 'the_content', array( SiteOrigin_Panels::single(), 'generate_post_content' ) )
820 - ) {
821 - remove_shortcode( 'learn_press_archive_course' );
822 - add_filter(
823 - 'the_content',
824 - array(
825 - $this,
826 - 'the_content_callback',
827 - ),
828 - $this->_filter_content_priority
829 - );
830 - }
831 - } else {
832 - $content = do_shortcode( $content );
833 - }
834 -
835 - if ( empty( $wp_query->post->ID ) || LEARNPRESS_IS_CATEGORY ) {
836 - $wp_query->post->ID = 0;
837 - }
838 -
839 - $wp_query->post->filter = 'raw';
840 - if ( learn_press_is_course_category() ) {
841 - $wp_query->post->post_title = single_term_title( '', false );
842 - }
843 -
844 - $wp_query->post->post_content = $content;
845 - $wp_query->posts = array( $wp_query->post );
846 -
847 - if ( is_post_type_archive( LP_COURSE_CPT ) || LEARNPRESS_IS_CATEGORY ) {
848 - $wp_query->is_page = false;
849 - $wp_query->is_archive = true;
850 - $wp_query->is_single = false;
851 - } else {
852 - $wp_query->found_posts = 1;
853 - $wp_query->is_single = true;
854 - $wp_query->is_preview = false;
855 - $wp_query->is_archive = false;
856 - $wp_query->is_date = false;
857 - $wp_query->is_year = false;
858 - $wp_query->is_month = false;
859 - $wp_query->is_day = false;
860 - $wp_query->is_time = false;
861 - $wp_query->is_author = false;
862 - $wp_query->is_category = false;
863 - $wp_query->is_tag = false;
864 - $wp_query->is_tax = false;
865 - $wp_query->is_search = false;
866 - $wp_query->is_feed = false;
867 - $wp_query->is_comment_feed = false;
868 - $wp_query->is_trackback = false;
869 - $wp_query->is_home = false;
870 - $wp_query->is_404 = false;
871 - $wp_query->is_comments_popup = false;
872 - $wp_query->is_paged = false;
873 - $wp_query->is_admin = false;
874 - $wp_query->is_attachment = false;
875 - $wp_query->is_singular = false;
876 - $wp_query->is_posts_page = false;
877 - $wp_query->is_post_type_archive = false;
878 - }
879 - }
880 -
881 - return $template;
882 - }
883 -
884 - /**
885 636 * Query courses if page is archive courses
886 637 *
887 638 * @param $q WP_Query
888 639 *
@@ -887,10 +638,11 @@
887 638 * @param $q WP_Query
888 639 *
889 640 * @return WP_Query
890 641 * @editor tungnx
891 - * @modify 4.1.2
892 642 * @throws Exception
643 + * @version 4.1.3
644 + * @since 3.0.0
893 645 */
894 646 public function pre_get_posts( WP_Query $q ): WP_Query {
895 647 // Affect only the main query and not in admin
896 648 if ( ! $q->is_main_query() && ! is_admin() ) {
@@ -896,194 +648,195 @@
896 648 if ( ! $q->is_main_query() && ! is_admin() ) {
897 649 return $q;
898 650 }
899 651
900 - // Exclude item not assign
901 - if ( $q->is_search() ) {
902 - // Exclude item not assign any course
903 - $course_item_types = learn_press_get_course_item_types();
904 - $list_ids_exclude = array();
652 + try {
653 + if ( LP_Page_Controller::is_page_courses() ) {
654 + if ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses()
655 + && ! LP_Settings::theme_no_support_load_courses_ajax() ) {
656 + /**
657 + * If page is archive course - query set posts_per_page = 1
658 + * For fastest - because when page loaded - call API to load list courses
659 + *
660 + * Current, apply only for LP, not apply for theme Thimpress, because theme override
661 + */
662 + $q->set( 'posts_per_page', 1 );
663 + $q->set( 'suppress_filters', true );
664 + //$q->set( 'posts_per_archive_page', 1 );
665 + //$q->set( 'nopaging', true );
666 + } else {
667 + $filter = new LP_Course_Filter();
668 + $filter->only_fields = [ 'ID' ];
669 + $filter->limit = - 1;
670 + $is_need_check_in_arr = false;
671 + $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
905 672
906 - foreach ( $course_item_types as $item_type ) {
907 - $filter = new LP_Post_Type_Filter();
908 - $filter->post_type = $item_type;
909 - $exclude_item = LP_Course_DB::getInstance()->get_item_ids_unassigned( $filter );
910 - $exclude_item = LP_Course_DB::get_values_by_key( $exclude_item );
673 + if ( LP_Settings_Courses::is_ajax_load_courses() &&
674 + LP_Settings_Courses::get_type_pagination() != 'number' &&
675 + ! LP_Settings::theme_no_support_load_courses_ajax() ) {
676 + $q->set( 'paged', 1 );
677 + }
911 678
912 - $list_ids_exclude = array_merge( $list_ids_exclude, $exclude_item );
913 - }
679 + $q->set( 'posts_per_page', $limit );
680 + // $q->set( 'cache_results', true ); // it default true
914 681
915 - // Exclude question not assign any quiz
916 - $question_ids = LP_Question_DB::getInstance()->get_questions_not_assign_quiz();
917 - $question_ids = LP_Course_DB::get_values_by_key( $question_ids );
918 - $list_ids_exclude = array_merge( $list_ids_exclude, $question_ids );
682 + // Search courses by keyword
683 + if ( ! empty( $_REQUEST['c_search'] ) ) {
684 + $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
685 + $is_need_check_in_arr = true;
686 + }
919 687
920 - if ( ! empty( $list_ids_exclude ) ) {
921 - $q->set( 'post__not_in', $list_ids_exclude );
922 - }
923 - }
688 + $author_ids_str = LP_Helper::sanitize_params_submitted( $_REQUEST['c_authors'] ?? 0 );
689 + if ( ! empty( $author_ids_str ) ) {
690 + $q->set( 'author', $author_ids_str );
691 + }
924 692
925 - $is_archive_course = false;
693 + // Search course has price/free
694 + $meta_query = [];
695 + if ( isset( $_REQUEST['sort_by'] ) ) {
696 + $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
697 + if ( 'on_paid' === $sort_by ) {
698 + $meta_query[] = array(
699 + 'key' => '_lp_price',
700 + 'value' => 0,
701 + 'compare' => '>',
702 + );
703 + }
926 704
927 - // Handle 404 if user are viewing course item directly.
928 - $this->set_link_item_course_default_wp_to_page_404( $q );
705 + if ( 'on_free' === $sort_by ) {
706 + $meta_query[] = array(
707 + 'relation' => 'OR',
708 + [
709 + 'key' => '_lp_price',
710 + 'value' => 0,
711 + 'compare' => '=',
712 + ],
713 + [
714 + 'key' => '_lp_price',
715 + 'value' => '',
716 + 'compare' => '=',
717 + ],
718 + [
719 + 'key' => '_lp_price',
720 + 'compare' => 'NOT EXISTS',
721 + ],
722 + );
723 + }
724 + }
929 725
930 - $this->_queried_object = ! empty( $q->queried_object_id ) ? $q->queried_object : false;
726 + // Search by level
727 + $c_level = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['c_level'] ?? '' ) );
728 + if ( ! empty( $c_level ) ) {
729 + $c_level = str_replace( 'all', '', $c_level );
730 + $c_level = explode( ',', $c_level );
731 + $meta_query[] = array(
732 + 'key' => '_lp_level',
733 + 'value' => $c_level,
734 + 'compare' => 'IN',
735 + );
736 + }
931 737
932 - /**
933 - * If current page is used for courses page
934 - * Set on both: "Homepage" and "Posts page" on Reading Settings
935 - */
936 - $page_courses_id = learn_press_get_page_id( 'courses' );
738 + $q->set( 'meta_query', $meta_query );
739 + // End Meta query
937 740
938 - if ( $q->is_home() && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) == $page_courses_id ) {
939 - $is_archive_course = 1;
940 - // $q->is_home = false;
941 - // $q->set( 'page_id', get_option( 'page_on_front' ) );
942 - }
741 + // Search on Category
742 + $args_cat = lp_archive_skeleton_get_args();
743 + $tax_query = [];
744 + $term_ids_str = LP_Helper::sanitize_params_submitted(
745 + urldecode( $_REQUEST['term_id'] ?? $args_cat['page_term_id_current'] ?? '' )
746 + );
747 + if ( ! empty( $term_ids_str ) ) {
748 + $term_ids = explode( ',', $term_ids_str );
943 749
944 - /**
945 - * If current page is used for courses page and set as "Homepage"
946 - */
947 - if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $page_courses_id && $q->get( 'page_id' ) == $page_courses_id ) {
948 - $is_archive_course = 1;
750 + $tax_query[] = array(
751 + 'taxonomy' => 'course_category',
752 + 'field' => 'term_id',
753 + 'terms' => $term_ids,
754 + 'operator' => 'IN',
755 + 'include_children' => false,
756 + );
757 + }
949 758
950 - /*
951 - global $wp_post_types;
759 + // Tag query
760 + $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['tag_id'] ?? '' ) );
761 + if ( ! empty( $tag_ids_str ) ) {
762 + $term_ids = explode( ',', $tag_ids_str );
952 763
953 - $course_page = get_post( $page_courses_id );
954 - $this->_queried_object = $course_page;
955 - $wp_post_types[ LP_COURSE_CPT ]->ID = $course_page->ID;
956 - $wp_post_types[ LP_COURSE_CPT ]->post_title = $course_page->post_title;
957 - $wp_post_types[ LP_COURSE_CPT ]->post_name = $course_page->post_name;
958 - $wp_post_types[ LP_COURSE_CPT ]->post_type = $course_page->post_type;
959 - $wp_post_types[ LP_COURSE_CPT ]->ancestors = get_ancestors( $course_page->ID, $course_page->post_type );*/
960 - }
764 + $tax_query[] = array(
765 + 'taxonomy' => 'course_tag',
766 + 'field' => 'term_id',
767 + 'terms' => $term_ids,
768 + 'operator' => 'IN',
769 + );
770 + }
961 771
962 - // Set custom posts per page
963 - if ( $this->_is_archive() ) {
964 - $is_archive_course = 1;
965 - }
772 + $q->set( 'tax_query', $tax_query );
773 + // End Tax query
966 774
967 - $apply_lazy_load_for_theme = apply_filters( 'lp/page/courses/query/lazy_load', false );
775 + // Author query
776 + if ( isset( $_REQUEST['c_author'] ) ) {
777 + $author_ids = LP_Helper::sanitize_params_submitted( $_REQUEST['c_author'] );
778 + $q->set( 'author__in', $author_ids );
779 + }
780 + // End Author query
968 781
969 - if ( $is_archive_course ) {
970 - if ( ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses() ) ) {
971 - LP()->template( 'course' )->remove_callback( 'learn-press/after-courses-loop', 'loop/course/pagination.php', 10 );
972 - /**
973 - * If page is archive course - query set posts_per_page = 1
974 - * For fastest - because when page loaded - call API to load list courses
975 - *
976 - * Current, apply only for LP, not apply for theme Thimpress, because theme override
977 - */
978 - $q->set( 'posts_per_page', 1 );
979 - $q->set( 'posts_per_archive_page', 1 );
980 - $q->set( 'nopaging', true );
981 - } else {
982 - $filter = new LP_Course_Filter();
983 - $filter->only_fields = [ 'ID' ];
984 - $filter->max_limit = $filter->limit = 1000;
985 - $is_need_check_in_arr = false;
986 - $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
782 + // Order query
783 + if ( isset( $_REQUEST['order_by'] ) ) {
784 + $order_by = LP_Helper::sanitize_params_submitted( $_REQUEST['order_by'] );
785 + $order = 'DESC';
987 786
988 - $q->set( 'posts_per_page', $limit );
989 - // $q->set( 'cache_results', true ); // it default true
787 + switch ( $order_by ) {
788 + case 'post_title':
789 + $order_by = 'title';
790 + $order = 'ASC';
791 + break;
792 + case 'popular':
793 + $filter->order_by = 'popular';
794 + $order_by = 'post__in';
795 + $is_need_check_in_arr = true;
796 + break;
797 + default:
798 + $order_by = 'date';
799 + break;
800 + }
990 801
991 - // Search courses by keyword
992 - // $q->set( 's', $_REQUEST['c_search'] ?? '' );
993 - if ( ! empty( $_REQUEST['c_search'] ) ) {
994 - $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
995 - $is_need_check_in_arr = true;
996 - }
997 -
998 - $author_ids_str = LP_Helper::sanitize_params_submitted( $_REQUEST['c_authors'] ?? 0 );
999 - if ( ! empty( $author_ids_str ) ) {
1000 - $q->set( 'author', $author_ids_str );
1001 - }
1002 -
1003 - // Meta query
1004 - $meta_query = [];
1005 - if ( isset( $_REQUEST['sort_by'] ) ) {
1006 - $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
1007 - if ( 'on_paid' === $sort_by ) {
1008 - $meta_query[] = array(
1009 - 'key' => '_lp_price',
1010 - 'value' => 0,
1011 - 'compare' => '>',
1012 - );
802 + $q->set( 'orderby', $order_by );
803 + $q->set( 'order', $order );
1013 804 }
1014 805
1015 - if ( 'on_free' === $sort_by ) {
1016 - $meta_query[] = array(
1017 - 'key' => '_lp_price',
1018 - 'value' => 0,
1019 - 'compare' => '=',
1020 - );
806 + if ( $is_need_check_in_arr ) {
807 + $posts_in = Courses::get_courses( $filter );
808 + if ( ! empty( $posts_in ) ) {
809 + $posts_in = LP_Database::get_values_by_key( $posts_in );
810 + $q->set( 'post__in', $posts_in );
811 + } else {
812 + $q->set( 'post__in', 0 );
813 + }
1021 814 }
1022 - }
1023 - $q->set( 'meta_query', $meta_query );
1024 - // End Meta query
1025 815
1026 - // Tax query
1027 - $tax_query = [];
1028 - $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['term_id'] ?? '' ) );
1029 - if ( ! empty( $term_ids_str ) ) {
1030 - $term_ids = explode( ',', $term_ids_str );
1031 -
1032 - $tax_query[] = array(
1033 - 'taxonomy' => 'course_category',
1034 - 'field' => 'term_id',
1035 - 'terms' => $term_ids,
1036 - 'operator' => 'IN',
1037 - );
816 + $q = apply_filters( 'lp/page-courses/query/legacy', $q );
1038 817 }
1039 818
1040 - $q->set( 'tax_query', $tax_query );
1041 - // End Tax query
819 + return $q;
820 + }
1042 821
1043 - // Author query
1044 - if ( isset( $_REQUEST['c_author'] ) ) {
1045 - $author_ids = LP_Helper::sanitize_params_submitted( $_REQUEST['c_author'] );
1046 - $q->set( 'author__in', $author_ids );
1047 - }
1048 - // End Author query
822 + // Exclude item not assign
823 + if ( $q->is_search() ) {
824 + return $q;
825 + }
1049 826
1050 - // Order query
1051 - if ( isset( $_REQUEST['order_by'] ) ) {
1052 - $order_by = LP_Helper::sanitize_params_submitted( $_REQUEST['order_by'] );
1053 - $order = 'DESC';
827 + // Handle 404 if user are viewing course item directly.
828 + $this->set_link_item_course_default_wp_to_page_404( $q );
1054 829
1055 - switch ( $order_by ) {
1056 - case 'post_title':
1057 - $order_by = 'title';
1058 - $order = 'ASC';
1059 - break;
1060 - case 'popular':
1061 - $filter->order_by = 'popular';
1062 - $order_by = 'post__in';
1063 - $is_need_check_in_arr = true;
1064 - break;
1065 - default:
1066 - $order_by = 'date';
1067 - break;
1068 - }
1069 -
1070 - $q->set( 'orderby', $order_by );
1071 - $q->set( 'order', $order );
830 + // set 404 if viewing single instructor but not logged
831 + $slug_instructor = get_query_var( 'instructor_name' );
832 + if ( get_query_var( 'is_single_instructor' ) ) {
833 + if ( empty( $slug_instructor ) && ! is_user_logged_in() ) {
834 + self::set_page_404();
1072 835 }
1073 -
1074 - if ( $is_need_check_in_arr ) {
1075 - $posts_in = LP_Course::get_courses( $filter );
1076 - if ( ! empty( $posts_in ) ) {
1077 - $posts_in = LP_Database::get_values_by_key( $posts_in );
1078 - $q->set( 'post__in', $posts_in );
1079 - } else {
1080 - $q->set( 'post__in', 0 );
1081 - }
1082 - }
1083 -
1084 - $q = apply_filters( 'lp/page-courses/query/legacy', $q );
1085 836 }
837 + } catch ( Throwable $e ) {
838 + error_log( $e->getMessage() );
1086 839 }
1087 840
1088 841 return $q;
1089 842 }
@@ -1094,27 +847,32 @@
1094 847 * Apply for user not admin, instructor, co-instructor
1095 848 *
1096 849 * @param WP_Query $q
1097 850 *
1098 - * @return mixed
1099 851 * @editor tungnx
1100 852 * @since 3.2.7.5
1101 853 */
1102 854 public function set_link_item_course_default_wp_to_page_404( $q ) {
1103 - if ( ! $q->is_main_query() || is_admin() ) {
1104 - return $q;
855 + $post_type_apply_404 = apply_filters(
856 + 'lp/page-controller/',
857 + array(
858 + LP_LESSON_CPT,
859 + LP_QUIZ_CPT,
860 + LP_QUESTION_CPT,
861 + 'lp_assignment',
862 + )
863 + );
864 +
865 + if ( ! isset( $q->query_vars['post_type'] ) || ! in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
866 + return;
1105 867 }
1106 868
1107 - $post_type_apply_404 = array( LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, 'lp_assignment' );
1108 -
1109 - if ( isset( $q->query_vars['post_type'] ) && in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
869 + try {
1110 870 $flag_load_404 = true;
1111 871 $user = wp_get_current_user();
1112 872 $post_author = 0;
1113 873
1114 874 if ( $user ) {
1115 - $post = null;
1116 -
1117 875 if ( isset( $_GET['preview_id'] ) ) {
1118 876 $post_id = absint( $_GET['preview_id'] );
1119 877 $post = get_post( $post_id );
1120 878 $post_author = $post->post_author;
@@ -1122,9 +880,9 @@
1122 880 $post_id = absint( $_GET['p'] );
1123 881 $post = get_post( $post_id );
1124 882 $post_author = $post->post_author;
1125 883 } else {
1126 - $post_author = LP_Database::getInstance()->getPostAuthorByTypeAndSlug( $q->query_vars['post_type'], $q->query_vars[ $q->query_vars['post_type'] ] );
884 + $post_author = LP_Database::getInstance()->getPostAuthorByTypeAndSlug( $q->query_vars['post_type'] ?? '', $q->query_vars['name'] ?? '' );
1127 885 }
1128 886
1129 887 if ( $user->has_cap( 'administrator' ) ) {
1130 888 $flag_load_404 = false;
@@ -1135,80 +893,295 @@
1135 893
1136 894 $flag_load_404 = apply_filters( 'learnpress/page/set-link-item-course-404', $flag_load_404, $post_author, $user );
1137 895
1138 896 if ( $flag_load_404 ) {
1139 - learn_press_404_page();
1140 - $q->set( 'post_type', '' );
897 + self::set_page_404();
1141 898 }
899 + } catch ( Throwable $e ) {
900 + error_log( $e->getMessage() );
1142 901 }
902 + }
1143 903
1144 - return $q;
904 + /**
905 + * Get page current on frontend
906 + *
907 + * @return string
908 + * @since 3.2.8
909 + * @author tungnx
910 + */
911 + public static function page_current(): string {
912 + /**
913 + * @var WP_Query $wp_query
914 + */
915 + global $wp_query;
916 +
917 + // Course Builder page detection
918 + if ( self::is_page_course_builder() ) {
919 + return LP_PAGE_COURSE_BUILDER;
920 + }
921 +
922 + if ( ! is_object( $wp_query ) || ! $wp_query->get_queried_object() ) {
923 + return '';
924 + }
925 +
926 + if ( self::is_page_checkout() ) {
927 + return LP_PAGE_CHECKOUT;
928 + } elseif ( LP_Global::course_item_quiz() ) {
929 + return LP_PAGE_QUIZ;
930 + } elseif ( learn_press_is_course() && LP_Global::course_item() ) {
931 + return LP_PAGE_SINGLE_COURSE_CURRICULUM;
932 + } elseif ( self::is_page_courses() ) {
933 + return LP_PAGE_COURSES;
934 + } elseif ( learn_press_is_course() ) {
935 + return LP_PAGE_SINGLE_COURSE;
936 + } elseif ( self::is_page_become_a_teacher() ) {
937 + return LP_PAGE_BECOME_A_TEACHER;
938 + } elseif ( self::is_page_profile() ) {
939 + return LP_PAGE_PROFILE;
940 + } elseif ( learn_press_is_instructors() ) {
941 + return LP_PAGE_INSTRUCTORS;
942 + } elseif ( self::is_page_instructor() ) {
943 + return LP_PAGE_INSTRUCTOR;
944 + } else {
945 + return apply_filters( 'learnpress/page/current', '' );
946 + }
1145 947 }
1146 948
1147 - public function the_content_callback( $content ) {
1148 - if ( $this->_archive_contents ) {
1149 - preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
1150 - $this->_shortcode_exists = ! empty( $results );
1151 - if ( $this->_shortcode_exists ) {
1152 - $this->_shortcode_tag = $results[0];
1153 - $content = str_replace( $this->_shortcode_tag, $this->_archive_contents, $content );
949 + /**
950 + * Check is page viewing
951 + *
952 + * @param string $name
953 + *
954 + * @return bool
955 + */
956 + public static function page_is( string $name = '' ): bool {
957 + $page_id = learn_press_get_page_id( $name );
958 + if ( ! $page_id || 'page' !== get_post_type( $page_id ) ) {
959 + return false;
960 + }
961 +
962 + // If pages of LP set to homepage will return false
963 + $link_page = urldecode( get_the_permalink( $page_id ) );
964 + $home_url = home_url( '/' );
965 + if ( $home_url === $link_page ) {
966 + return false;
967 + }
968 +
969 + $page_profile_option = untrailingslashit( $link_page );
970 + $page_profile_option = str_replace( '/', '\/', $page_profile_option );
971 + $pattern = "/^$page_profile_option/";
972 + if ( preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
973 + return true;
974 + }
975 +
976 + return false;
977 + }
978 +
979 + /**
980 + * Check is page is single course
981 + *
982 + * @since 4.2.7.6
983 + * @version 1.0.0
984 + * @return bool
985 + */
986 + public static function is_page_single_course(): bool {
987 + static $flag;
988 + if ( ! is_null( $flag ) ) {
989 + return $flag;
990 + }
991 +
992 + try {
993 + $flag = is_singular( LP_COURSE_CPT );
994 + } catch ( Throwable $e ) {
995 + $flag = false;
996 + }
997 +
998 + return $flag;
999 + }
1000 +
1001 + /**
1002 + * Check is page courses
1003 + *
1004 + * @return bool
1005 + */
1006 + public static function is_page_courses(): bool {
1007 + static $flag;
1008 + if ( ! is_null( $flag ) ) {
1009 + return $flag;
1010 + }
1011 +
1012 + $is_tag = is_tax( LP_COURSE_TAXONOMY_TAG );
1013 + $is_category = is_tax( LP_COURSE_CATEGORY_TAX );
1014 +
1015 + if ( $is_category || $is_tag || is_post_type_archive( 'lp_course' ) ) {
1016 + $flag = true;
1017 + } else {
1018 + $page_courses_id = learn_press_get_page_id( 'courses' );
1019 + $page_courses_url = untrailingslashit( get_the_permalink( $page_courses_id ) );
1020 + if ( empty( $page_courses_url ) ) {
1021 + $page_courses_url = home_url( 'courses' );
1022 + }
1023 +
1024 + $page_courses_regex = str_replace( '/', '\/', $page_courses_url );
1025 + $pattern = '/' . $page_courses_regex . '\/?(page\/[0-9]*)?$/';
1026 + if ( preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
1027 + $flag = true;
1154 1028 } else {
1155 - $content .= $this->_archive_contents;
1029 + $flag = false;
1156 1030 }
1157 1031 }
1158 1032
1159 - return $content;
1033 + return $flag;
1160 1034 }
1161 1035
1162 1036 /**
1037 + * Check is page profile
1038 + *
1039 + * @return bool
1040 + */
1041 + public static function is_page_profile(): bool {
1042 + static $flag;
1043 + if ( ! is_null( $flag ) ) {
1044 + return $flag;
1045 + }
1046 +
1047 + $flag = self::page_is( 'profile' );
1048 +
1049 + return $flag;
1050 + }
1051 +
1052 + /**
1053 + * Check is page instructor
1054 + *
1055 + * @return bool
1056 + */
1057 + public static function is_page_instructors(): bool {
1058 + static $flag;
1059 + if ( ! is_null( $flag ) ) {
1060 + return $flag;
1061 + }
1062 +
1063 + $flag = self::page_is( 'instructors' );
1064 +
1065 + return $flag;
1066 + }
1067 +
1068 + /**
1069 + * Check is page instructor
1070 + *
1071 + * @return bool
1072 + */
1073 + public static function is_page_instructor(): bool {
1074 + global $wp_query;
1075 + static $flag;
1076 + if ( ! is_null( $flag ) ) {
1077 + return $flag;
1078 + }
1079 +
1080 + $flag = false;
1081 + if ( $wp_query->get( 'is_single_instructor' ) ) {
1082 + $flag = true;
1083 + }
1084 +
1085 + return $flag;
1086 + }
1087 +
1088 + /**
1089 + * Check is page profile
1090 + *
1091 + * @return bool
1092 + */
1093 + public static function is_page_checkout(): bool {
1094 + return self::page_is( 'checkout' );
1095 + }
1096 +
1097 + /**
1163 1098 * Check is page Become a teacher
1164 1099 *
1165 - * @return bool|mixed|void
1100 + * @return bool
1166 1101 * @since 3.2.8
1167 1102 * @author tungnx
1168 1103 */
1169 - public static function is_page_become_a_teacher() {
1170 - $page_id = learn_press_get_page_id( 'become_a_teacher' );
1104 + public static function is_page_become_a_teacher(): bool {
1105 + return self::page_is( 'become_a_teacher' );
1106 + }
1171 1107
1172 - if ( $page_id && is_page( $page_id ) ) {
1108 + /**
1109 + * Check page is LP Ajax
1110 + *
1111 + * @return bool
1112 + * @since 4.2.7.7
1113 + */
1114 + public static function is_page_lp_ajax(): bool {
1115 + // If pages of LP set to homepage will return false
1116 + $pattern = '/lp-ajax-handle/';
1117 + if ( preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
1173 1118 return true;
1174 1119 }
1175 1120
1176 - return apply_filters( 'learnpress/is-page/become-a-teacher', false );
1121 + return false;
1177 1122 }
1178 1123
1179 1124 /**
1180 - * Get page current on frontend
1125 + * Redirect admin to course builder if hide instructor access admin screen
1181 1126 *
1127 + * @since 4.3.6
1128 + * @version 1.0.0
1129 + */
1130 + public function redirect_admin_to_course_builder() {
1131 + // Skip AJAX requests
1132 + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1133 + return;
1134 + }
1135 +
1136 + // Check hide instructor access admin screen
1137 + $hide_instructor_access_admin_screen = LP_Settings::is_hide_instructor_access_admin_screen();
1138 + if ( $hide_instructor_access_admin_screen
1139 + && current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
1140 + $cb_url = CourseBuilder::get_link_course_builder();
1141 +
1142 + // Avoid infinite redirect
1143 + if ( strpos( LP_Helper::getUrlCurrent(), $cb_url ) !== false ) {
1144 + return;
1145 + }
1146 +
1147 + wp_redirect( $cb_url );
1148 + exit;
1149 + }
1150 + }
1151 +
1152 + public static function is_page_course_builder(): bool {
1153 + /** @var WP_Query $wp_query */
1154 + global $wp_query;
1155 + return $wp_query->get( 'is_course_builder' );
1156 + }
1157 +
1158 + /**
1159 + * Get link page by name
1160 + *
1161 + * @param string $page_name
1162 + * @param array $args
1163 + * @param bool $no_cache
1164 + *
1182 1165 * @return string
1183 - * @since 3.2.8
1184 - * @author tungnx
1166 + * @since 4.2.7.8
1167 + * @version 1.0.0
1185 1168 */
1186 - public static function page_current(): string {
1187 - if ( learn_press_is_checkout() ) {
1188 - return LP_PAGE_CHECKOUT;
1189 - } elseif ( LP_Global::course_item_quiz() ) {
1190 - return LP_PAGE_QUIZ;
1191 - } elseif ( learn_press_is_course() && is_single() && LP_Global::course_item() ) {
1192 - return LP_PAGE_SINGLE_COURSE_CURRICULUM;
1193 - } elseif ( learn_press_is_courses() ) {
1194 - return LP_PAGE_COURSES;
1195 - } elseif ( learn_press_is_course() ) {
1196 - return LP_PAGE_SINGLE_COURSE;
1197 - } elseif ( self::is_page_become_a_teacher() ) {
1198 - return LP_PAGE_BECOME_A_TEACHER;
1199 - } elseif ( learn_press_is_profile() ) {
1200 - return LP_PAGE_PROFILE;
1201 - } else {
1202 - return apply_filters( 'learnpress/page/current', '' );
1169 + public static function get_link_page( string $page_name, array $args = [], bool $no_cache = false ): string {
1170 + $page_link = learn_press_get_page_link( $page_name );
1171 +
1172 + if ( ! empty( $args ) ) {
1173 + $page_link = add_query_arg( $args, $page_link );
1203 1174 }
1175 +
1176 + if ( $no_cache ) {
1177 + $page_link = LP_Helper::get_link_no_cache( $page_link );
1178 + }
1179 +
1180 + return $page_link;
1204 1181 }
1205 1182
1206 1183 public static function instance() {
1207 - if ( is_admin() ) {
1208 - return null;
1209 - }
1210 -
1211 1184 if ( ! self::$_instance ) {
1212 1185 self::$_instance = new self();
1213 1186 }
1214 1187
@@ -1220,10 +1193,14 @@
1220 1193 *
1221 1194 * @editor tungnx
1222 1195 * @version 1.0.1
1223 1196 * @since 3.0.0
1197 + * @deprecated 4.1.7.3
1224 1198 */
1225 1199 public function learn_press_edit_admin_bar() {
1200 + _deprecated_function( __METHOD__, '4.1.7.3' );
1201 + return;
1202 +
1226 1203 global $wp_admin_bar;
1227 1204
1228 1205 $current_user = wp_get_current_user();
1229 1206
@@ -1231,11 +1208,11 @@
1231 1208 return;
1232 1209 }
1233 1210
1234 1211 $page_profile_id = learn_press_get_page_id( 'profile' );
1235 -
1236 1212 if ( $page_profile_id && get_post_status( $page_profile_id ) != 'trash' ) {
1237 1213 $user_id = $current_user->ID;
1214 + $profile = LP_Profile::instance( $user_id );
1238 1215
1239 1216 $wp_admin_bar->add_menu(
1240 1217 array(
1241 1218 'id' => 'course_profile',
@@ -1240,12 +1217,109 @@
1240 1217 array(
1241 1218 'id' => 'course_profile',
1242 1219 'parent' => 'user-actions',
1243 1220 'title' => get_the_title( $page_profile_id ),
1244 - 'href' => learn_press_user_profile_link( $user_id, false ),
1221 + 'href' => $profile->get_tab_link(),
1245 1222 )
1246 1223 );
1247 1224 }
1248 1225 }
1226 +
1227 + /**
1228 + * Set again HTTP_X_WP_NONCE when cache make 403 error.
1229 + *
1230 + * @param $send_no_cache_headers
1231 + *
1232 + * @return mixed
1233 + * @since 4.1.7
1234 + * @version 1.0.0
1235 + */
1236 + public function check_x_wp_nonce_cache( $send_no_cache_headers ) {
1237 + if ( ! $send_no_cache_headers && ! is_admin() && $_SERVER['REQUEST_METHOD'] == 'GET' && LP_Helper::isRestApiLP() ) {
1238 + $nonce = wp_create_nonce( 'wp_rest' );
1239 + $_SERVER['HTTP_X_WP_NONCE'] = $nonce;
1240 + }
1241 +
1242 + return $send_no_cache_headers;
1243 + }
1244 +
1245 + /**
1246 + * Override lesson comment permalink.
1247 + *
1248 + * @param string $link The comment permalink with '#comment-$id' appended.
1249 + * @param WP_Comment $comment The current comment object.
1250 + *
1251 + * @return string $link The comment permalink with '#comment-$id' appended.
1252 + * @since 4.2.3
1253 + * @version 1.0.0
1254 + */
1255 + public function edit_lesson_comment_links( $link, $comment ): string {
1256 + try {
1257 + $comment = get_comment( $comment );
1258 + if ( get_post_type( $comment->comment_post_ID ) == LP_LESSON_CPT ) {
1259 + $link = wp_get_referer() . '#comment-' . $comment->comment_ID;
1260 + }
1261 +
1262 + return $link;
1263 + } catch ( Throwable $e ) {
1264 + error_log( $e->getMessage() );
1265 + }
1266 +
1267 + return $link;
1268 + }
1269 +
1270 + /**
1271 + * Set menu active for page courses.
1272 + *
1273 + * @param $menu_items
1274 + *
1275 + * @return mixed
1276 + */
1277 + public function menu_active( $menu_items ) {
1278 + $course_page = learn_press_get_page_id( 'courses' );
1279 + $page_for_posts = (int) get_option( 'page_for_posts' );
1280 +
1281 + if ( is_array( $menu_items ) && ! empty( $menu_items ) ) {
1282 + foreach ( $menu_items as $key => $menu_item ) {
1283 + $classes = (array) $menu_item->classes;
1284 + $menu_id = (int) $menu_item->object_id;
1285 +
1286 + // Unset active class for blog page.
1287 + if ( $page_for_posts === $menu_id ) {
1288 + $menu_item->current = false;
1289 +
1290 + if ( in_array( 'current_page_parent', $classes, true ) ) {
1291 + unset( $classes[ array_search( 'current_page_parent', $classes, true ) ] );
1292 + }
1293 +
1294 + if ( in_array( 'current-menu-item', $classes, true ) ) {
1295 + unset( $classes[ array_search( 'current-menu-item', $classes, true ) ] );
1296 + }
1297 + } elseif ( ( is_post_type_archive( 'lp_course' ) || is_page( $course_page ) ) && $course_page === $menu_id && 'page' === $menu_item->object ) {
1298 + // Set active state if this is the shop page link.
1299 + $menu_item->current = true;
1300 + $classes[] = 'current-menu-item';
1301 + $classes[] = 'current_page_item';
1302 + } elseif ( is_singular( 'lp_course' ) && $course_page === $menu_id ) {
1303 + // Set parent state if this is a product page.
1304 + $classes[] = 'current_page_parent';
1305 + }
1306 +
1307 + $menu_item->classes = array_unique( $classes );
1308 + $menu_items[ $key ] = $menu_item;
1309 + }
1310 + }
1311 +
1312 + return $menu_items;
1313 + }
1314 +
1315 + /**
1316 + * Set Page viewing to 404
1317 + *
1318 + * @return void
1319 + */
1320 + public static function set_page_404() {
1321 + global $wp_query;
1322 + $wp_query->set_404();
1323 + status_header( 404 );
1324 + }
1249 1325 }
1250 -
1251 -return LP_Page_Controller::instance();