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 +643 -374 4.2.04.4.8 View file →
@@ -1,6 +1,12 @@
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 {
@@ -28,34 +34,122 @@
28 34 /**
29 35 * LP_Page_Controller constructor.
30 36 */
31 37 protected function __construct() {
32 - add_filter( 'post_type_archive_link', [ $this, 'link_archive_course' ], 10, 2 );
33 - add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), -1 );
34 - add_filter( 'template_include', array( $this, 'template_loader' ), 10 );
35 - add_filter( 'template_include', array( $this, 'check_pages' ), 30 );
36 - 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 );
37 40
38 - add_filter( 'the_post', array( $this, 'setup_data_for_item_course' ) );
39 - 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 + }
40 46
41 - add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
42 - 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 + }
43 68
44 - // Yoast seo
45 - add_filter( 'wpseo_opengraph_desc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
46 - 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 ';
47 72
48 - // edit link item course when form search default wp
49 - add_filter( 'post_type_link', array( $this, 'post_type_link' ), 10, 2 );
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 );
50 83
51 - // Set link profile to admin menu
52 - //add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
84 + add_filter( 'the_post', array( $this, 'setup_data_for_item_course' ) );
85 + add_filter( 'request', array( $this, 'remove_course_post_format' ), 1 );
53 86
54 - // Web hook detected PayPal request.
55 - add_action( 'init', [ $this, 'check_webhook_paypal_ipn' ] );
56 - // Set again x-wp-nonce on header when has cache with not login.
57 - add_filter( 'rest_send_nocache_headers', array( $this, 'check_x_wp_nonce_cache' ) );
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 );
89 +
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 );
93 +
94 + // Set link profile to admin menu
95 + //add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
96 +
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 + );
115 + }
116 +
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 + }
128 +
129 + return $post_types;
130 + }
131 + );
132 +
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 + }
146 +
147 + return $is_viewable;
148 + },
149 + 10,
150 + 2
151 + );*/
58 152 }
59 153
60 154 /**
61 155 * Set link archive course.
@@ -73,9 +167,9 @@
73 167 return $link;
74 168 }
75 169
76 170 /**
77 - * Set link item course when form search default wp
171 + * Set link course, item course
78 172 *
79 173 * @param string $post_link
80 174 * @param object $post
81 175 */
@@ -80,20 +174,19 @@
80 174 * @param object $post
81 175 */
82 176 public function post_type_link( $post_link, $post ) {
83 177 // Set item's course permalink
84 - $course_item_types = learn_press_get_course_item_types();
178 + $course_item_types = CourseModel::item_types_support();
85 179 $item_id = $post->ID;
86 180
87 - 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() ) {
88 183 $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id );
89 -
90 184 if ( ! $section_id ) {
91 185 return $post_link;
92 186 }
93 187
94 188 $course_id = LP_Section_DB::getInstance()->get_course_id_by_section( $section_id );
95 -
96 189 if ( ! $course_id ) {
97 190 return $post_link;
98 191 }
99 192
@@ -103,113 +196,15 @@
103 196 }
104 197
105 198 $post_link = $course->get_item_link( $item_id );
106 199 } elseif ( LP_COURSE_CPT === $post->post_type ) {
107 - // Abort early if the placeholder rewrite tag isn't in the generated URL
108 - if ( false === strpos( $post_link, '%' ) ) {
109 - return $post_link;
110 - }
111 -
112 - // Get the custom taxonomy terms in use by this post
113 - $terms = get_the_terms( $post->ID, 'course_category' );
114 -
115 - if ( ! empty( $terms ) ) {
116 - $terms = _learn_press_usort_terms_by_ID( $terms ); // order by ID
117 - $category_object = apply_filters(
118 - 'learn_press_course_post_type_link_course_category',
119 - $terms[0],
120 - $terms,
121 - $post
122 - );
123 - $category_object = get_term( $category_object, 'course_category' );
124 - $course_category = $category_object->slug;
125 -
126 - $parent = $category_object->parent;
127 - if ( $parent ) {
128 - $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
129 - foreach ( $ancestors as $ancestor ) {
130 - $ancestor_object = get_term( $ancestor, 'course_category' );
131 - $course_category = $ancestor_object->slug . '/' . $course_category;
132 - }
133 - }
134 - } else {
135 - // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
136 - $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
137 - }
138 -
139 - $find = array(
140 - '%year%',
141 - '%monthnum%',
142 - '%day%',
143 - '%hour%',
144 - '%minute%',
145 - '%second%',
146 - '%post_id%',
147 - '%category%',
148 - '%course_category%',
149 - );
150 -
151 - $replace = array(
152 - date_i18n( 'Y', strtotime( $post->post_date ) ),
153 - date_i18n( 'm', strtotime( $post->post_date ) ),
154 - date_i18n( 'd', strtotime( $post->post_date ) ),
155 - date_i18n( 'H', strtotime( $post->post_date ) ),
156 - date_i18n( 'i', strtotime( $post->post_date ) ),
157 - date_i18n( 's', strtotime( $post->post_date ) ),
158 - $post->ID,
159 - $course_category,
160 - $course_category,
161 - );
162 -
163 - $post_link = str_replace( $find, $replace, $post_link );
200 + // Link single course (with %course_category%).
201 + $post_link = LP_Helper::handle_lp_permalink_structure( $post_link, $post );
164 202 }
165 203
166 204 return $post_link;
167 205 }
168 206
169 - private function has_block_template( $template_name ) {
170 - if ( ! $template_name ) {
171 - return false;
172 - }
173 -
174 - $has_template = false;
175 - $template_name = str_replace( 'course', LP_COURSE_CPT, $template_name );
176 - $template_filename = $template_name . '.html';
177 - // Since Gutenberg 12.1.0, the conventions for block templates directories have changed,
178 - // we should check both these possible directories for backwards-compatibility.
179 - $possible_templates_dirs = array( 'templates', 'block-templates' );
180 -
181 - // Combine the possible root directory names with either the template directory
182 - // or the stylesheet directory for child themes, getting all possible block templates
183 - // locations combinations.
184 - $filepath = DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template_filename;
185 - $legacy_filepath = DIRECTORY_SEPARATOR . 'block-templates' . DIRECTORY_SEPARATOR . $template_filename;
186 - $possible_paths = array(
187 - get_stylesheet_directory() . $filepath,
188 - get_stylesheet_directory() . $legacy_filepath,
189 - get_template_directory() . $filepath,
190 - get_template_directory() . $legacy_filepath,
191 - );
192 -
193 - // Check the first matching one.
194 - foreach ( $possible_paths as $path ) {
195 - if ( is_readable( $path ) ) {
196 - $has_template = true;
197 - break;
198 - }
199 - }
200 -
201 - /**
202 - * Filters the value of the result of the block template check.
203 - *
204 - * @since x.x.x
205 - *
206 - * @param boolean $has_template value to be filtered.
207 - * @param string $template_name The name of the template.
208 - */
209 - return (bool) apply_filters( 'learnpress_has_block_template', $has_template, $template_name );
210 - }
211 -
212 207 /**
213 208 * Set title of pages
214 209 *
215 210 * 1. Title course archive page
@@ -218,15 +213,16 @@
218 213 *
219 214 * @param string $title
220 215 *
221 216 * @return string
217 + * @throws Exception
218 + * @since 3.2.7.7
219 + * @version 1.0.2
222 220 * @author tungnx
223 - * @since 3.2.7.7
224 - * @version 1.0.1
225 221 */
226 222 public function set_title_pages( $title = '' ): string {
227 - global $wp_query;
228 223 $flag_title_course = false;
224 + $user_id = get_current_user_id();
229 225
230 226 $course_archive_page_id = LP_Settings::get_option( 'courses_page_id', 0 );
231 227
232 228 // Set title single course.
@@ -236,21 +232,33 @@
236 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
237 233
238 234 $flag_title_course = true;
239 235 }
240 - } elseif ( learn_press_is_courses() ) { // Set title course archive page.
241 - if ( learn_press_is_search() ) {
236 + } elseif ( LP_Page_Controller::is_page_courses() ) { // Set title course archive page.
237 + if ( isset( $_GET['c_search'] ) ) {
242 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 + }
243 247 } else {
244 248 $title = $course_archive_page_id ? get_the_title( $course_archive_page_id ) : __( 'Courses', 'learnpress' );
245 249 }
246 250
247 251 $flag_title_course = true;
248 - } elseif ( learn_press_is_profile() ) {
249 - $profile = LP_Profile::instance();
250 - $tab_slug = $profile->get_current_tab();
251 - $tab = $profile->get_tab_at( $tab_slug );
252 - $page_id = learn_press_get_page_id( 'profile' );
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 + }
253 261
254 262 if ( $page_id ) {
255 263 $page_title = get_the_title( $page_id );
256 264 } else {
@@ -255,8 +263,9 @@
255 263 $page_title = get_the_title( $page_id );
256 264 } else {
257 265 $page_title = '';
258 266 }
267 +
259 268 if ( $tab instanceof LP_Profile_Tab ) {
260 269 $title = join(
261 270 ' ',
262 271 apply_filters(
@@ -267,8 +276,10 @@
267 276 $tab->get( 'title' ),
268 277 )
269 278 )
270 279 );
280 + } else {
281 + $title = $page_title;
271 282 }
272 283
273 284 $flag_title_course = true;
274 285 }
@@ -276,9 +287,9 @@
276 287 if ( $flag_title_course ) {
277 288 $title .= ' - ' . get_bloginfo( 'name', 'display' );
278 289 }
279 290
280 - if ( empty( $title ) ) {
291 + if ( ! is_string( $title ) ) {
281 292 $title = get_bloginfo( 'name', 'display' );
282 293 }
283 294
284 295 return apply_filters( 'learn-press/title-page', $title );
@@ -307,56 +318,19 @@
307 318
308 319 return $desc;
309 320 }
310 321
311 - public function check_pages( $template ) {
312 - if ( learn_press_is_checkout() ) {
313 - $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
314 -
315 - if ( ! $available_gateways ) {
316 - learn_press_add_message( __( 'No payment method is available.', 'learnpress' ), 'error' );
317 - }
318 - } else {
319 - global $wp_query;
320 -
321 - $logout_slug = learn_press_profile_logout_slug();
322 -
323 - if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
324 - wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
325 - exit;
326 - }
327 - }
328 -
329 - return $template;
330 - }
331 -
332 322 /**
333 - * Auto inserting a registered shortcode to a specific page
334 - * if that page is viewing in single mode.
335 - *
336 - * @param string $template
337 - *
338 - * @return string;
339 - * @since 3.3.0
323 + * Handle logout
340 324 */
341 - public function auto_shortcode( $template ) {
342 - global $post;
343 - $the_post = $post;
344 - if ( $the_post && is_page( $the_post->ID ) ) {
325 + public function logout( $template ) {
326 + global $wp_query;
345 327
346 - // Filter here to insert the shortcode
347 - $auto_shortcodes = apply_filters( 'learn-press/auto-shortcode-pages', array() );
328 + $logout_slug = learn_press_profile_logout_slug();
348 329
349 - if ( ! empty( $auto_shortcodes[ $the_post->ID ] ) ) {
350 - $shortcode_tag = $auto_shortcodes[ $the_post->ID ];
351 -
352 - preg_match( '/\[' . $shortcode_tag . '\s?(.*)\]/', $the_post->post_content, $results );
353 -
354 - if ( empty( $results ) ) {
355 - $content = $the_post->post_content . "[$shortcode_tag]";
356 - $the_post->post_content = $content;
357 - }
358 - }
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;
359 333 }
360 334
361 335 return $template;
362 336 }
@@ -377,8 +351,12 @@
377 351 * @var LP_Course $lp_course
378 352 * @var LP_Course_Item|LP_Quiz|LP_Lesson $lp_course_item
379 353 */
380 354 global $wp, $wp_query, $lp_course_item;
355 + $vars = $wp->query_vars;
356 + if ( empty( $vars['course-item'] ) ) {
357 + return $post;
358 + }
381 359
382 360 if ( LP_COURSE_CPT !== $post->post_type ) {
383 361 return $post;
384 362 }
@@ -388,8 +366,20 @@
388 366 return $post;
389 367 }
390 368
391 369 /**
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
377 + */
378 + global $lpCourseModel;
379 + $lpCourseModel = CourseModel::find( $course->get_id(), true );
380 +
381 + /**
392 382 * @deprecated v4.1.6.1 LearnPress::instance()->global['course'], $GLOBALS['course']
393 383 * Some theme still use: global $course; LearnPress::instance()->global['course']
394 384 */
395 385 //LearnPress::instance()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
@@ -394,18 +384,12 @@
394 384 */
395 385 //LearnPress::instance()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
396 386 LearnPress::instance()->global['course'] = $GLOBALS['course'] = $course;
397 387
398 - if ( wp_verify_nonce( LP_Request::get( 'preview' ), 'preview-' . $post->ID ) ) {
388 + if ( wp_verify_nonce( LP_Request::get_param( 'preview' ), 'preview-' . $post->ID ) ) {
399 389 $GLOBALS['preview_course'] = $post->ID;
400 390 }
401 391
402 - $vars = $wp->query_vars;
403 -
404 - if ( empty( $vars['course-item'] ) ) {
405 - return $post;
406 - }
407 -
408 392 if ( ! $wp_query->is_main_query() ) {
409 393 return $post;
410 394 }
411 395
@@ -412,14 +396,10 @@
412 396 try {
413 397 $user = learn_press_get_current_user();
414 398
415 399 // If item name is set in query vars
416 - if ( ! is_numeric( $vars['course-item'] ) ) {
417 - $item_type = $vars['item-type'];
418 - $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
419 - } else {
420 - $post_item = get_post( absint( $vars['course-item'] ) );
421 - }
400 + $item_type = $vars['item-type'];
401 + $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
422 402
423 403 if ( ! $post_item ) {
424 404 return $post;
425 405 }
@@ -431,29 +411,15 @@
431 411 }
432 412
433 413 // Set item viewing
434 414 $user->set_viewing_item( $lp_course_item );
435 - } catch ( Exception $ex ) {
436 - learn_press_add_message( $ex->getMessage(), 'error' );
415 + } catch ( Throwable $e ) {
416 + error_log( $e->getMessage() );
437 417 }
438 418
439 419 return $post;
440 420 }
441 421
442 - /**
443 - * Set page 404
444 - *
445 - * @return mixed
446 - * @editor tungnx
447 - * @reason not use
448 - * @deprecated 4.0.0
449 - */
450 - /*
451 - public function set_404( $is_404 ) {
452 - global $wp_query;
453 - $wp_query->is_404 = $this->_is_404 = (bool) $is_404;
454 - }*/
455 -
456 422 public function is_404() {
457 423 return apply_filters( 'learn-press/query/404', $this->_is_404 );
458 424 }
459 425
@@ -477,17 +443,23 @@
477 443 }
478 444
479 445 /**
480 446 * @return bool
447 + * @deprecated v4.2.7.6
481 448 */
482 449 protected function _is_archive() {
450 + _deprecated_function( __METHOD__, '4.1.7.3' );
451 + return false;
483 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();
484 453 }
485 454
486 455 /**
487 456 * @return bool
457 + * @deprecated v4.2.7.6
488 458 */
489 459 protected function _is_single() {
460 + _deprecated_function( __METHOD__, '4.1.7.3' );
461 + return false;
490 462 return learn_press_is_course() && is_single();
491 463 }
492 464
493 465 /**
@@ -497,8 +469,11 @@
497 469 *
498 470 * @return bool|string
499 471 */
500 472 public function template_loader( $template ) {
473 + if ( wp_is_block_theme() ) {
474 + return $template;
475 + }
501 476
502 477 if ( is_embed() ) {
503 478 return $template;
504 479 }
@@ -527,8 +502,18 @@
527 502 return $template;
528 503 }
529 504
530 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 + /**
531 516 * Get the default filename for a template.
532 517 *
533 518 * @return string
534 519 * @since 4.0.0
@@ -534,40 +519,59 @@
534 519 * @since 4.0.0
535 520 */
536 521 private function get_page_template() {
537 522 $page_template = '';
523 + $object = get_queried_object();
538 524
539 - if ( is_singular( LP_COURSE_CPT ) ) {
540 - 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
541 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';
542 544 }
543 545
544 - if ( $this->_is_single() ) {
545 - global $post;
546 - setup_postdata( $post );
546 + // Old single course layout.
547 + //$page_template = 'single-course.php';
547 548
548 - $course_item = LP_Global::course_item();
549 - if ( $course_item && ! self::has_block_template( 'content-single-course-item' ) ) {
550 - $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';
551 559 }
552 560 }
553 561 } elseif ( learn_press_is_course_taxonomy() ) {
554 - $object = get_queried_object();
555 -
556 562 if ( is_tax( 'course_category' ) || is_tax( 'course_tag' ) ) {
557 563 $page_template = 'taxonomy-' . $object->taxonomy . '.php';
558 564
559 - if ( self::has_block_template( 'taxonomy-' . $object->taxonomy ) ) {
560 - $page_template = '';
561 - } 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 ) ) ) {
562 566 $page_template = 'archive-course.php';
563 567 }
564 - } elseif ( ! self::has_block_template( 'archive-course' ) ) {
568 + } else {
565 569 $page_template = 'archive-course.php';
566 570 }
567 - } 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() ) {
568 572 $page_template = 'archive-course.php';
569 - } elseif ( learn_press_is_checkout() && ! self::has_block_template( 'page-lp_checkout' ) ) {
573 + } elseif ( learn_press_is_checkout() ) {
570 574 $page_template = 'pages/checkout.php';
571 575 }
572 576
573 577 return apply_filters( 'learn-press/page-template', $page_template );
@@ -588,9 +592,9 @@
588 592 }
589 593 }
590 594 }
591 595
592 - if ( is_singular( LP_COURSE_CPT ) ) {
596 + /*if ( is_singular( LP_COURSE_CPT ) ) {
593 597 $object = get_queried_object();
594 598 $name_decoded = urldecode( $object->post_name );
595 599
596 600 if ( $name_decoded !== $object->post_name ) {
@@ -597,9 +601,9 @@
597 601 $templates[] = "single-course-$name_decoded.php";
598 602 }
599 603
600 604 $templates[] = "single-product-$object->post_name.php";
601 - }
605 + }*/
602 606
603 607 if ( learn_press_is_course_taxonomy() ) {
604 608 $object = get_queried_object();
605 609 $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
@@ -614,36 +618,8 @@
614 618 return array_unique( $templates );
615 619 }
616 620
617 621 /**
618 - * Filter to allow search more templates in theme for wp page template hierarchy.
619 - * Theme twentytwenty used 'singular.php' instead of 'page.php'
620 - *
621 - * @param array $templates
622 - *
623 - * @return array
624 - * @since 3.x.x
625 - * @deprecated 4.1.6.9.2
626 - */
627 - /*public function page_template_hierarchy( $templates ) {
628 - $templates = array_merge( $templates, array( 'singular.php' ) );
629 -
630 - return $templates;
631 - }*/
632 -
633 - /**
634 - * Archive course content.
635 - *
636 - * @return false|string
637 - */
638 - public function archive_content() {
639 - ob_start();
640 - learn_press_get_template( 'content-archive-course.php' );
641 -
642 - return ob_get_clean();
643 - }
644 -
645 - /**
646 622 * @param $title
647 623 *
648 624 * @return mixed
649 625 */
@@ -662,11 +638,11 @@
662 638 * @param $q WP_Query
663 639 *
664 640 * @return WP_Query
665 641 * @editor tungnx
642 + * @throws Exception
643 + * @version 4.1.3
666 644 * @since 3.0.0
667 - * @version 4.1.3
668 - * @throws Exception
669 645 */
670 646 public function pre_get_posts( WP_Query $q ): WP_Query {
671 647 // Affect only the main query and not in admin
672 648 if ( ! $q->is_main_query() && ! is_admin() ) {
@@ -673,11 +649,11 @@
673 649 return $q;
674 650 }
675 651
676 652 try {
677 - if ( LP_Page_Controller::page_current() === LP_PAGE_COURSES ) {
678 - if ( ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses() ) ) {
679 - LearnPress::instance()->template( 'course' )->remove_callback( 'learn-press/after-courses-loop', 'loop/course/pagination.php', 10 );
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() ) {
680 656 /**
681 657 * If page is archive course - query set posts_per_page = 1
682 658 * For fastest - because when page loaded - call API to load list courses
683 659 *
@@ -683,22 +659,28 @@
683 659 *
684 660 * Current, apply only for LP, not apply for theme Thimpress, because theme override
685 661 */
686 662 $q->set( 'posts_per_page', 1 );
687 - $q->set( 'posts_per_archive_page', 1 );
688 - $q->set( 'nopaging', true );
663 + $q->set( 'suppress_filters', true );
664 + //$q->set( 'posts_per_archive_page', 1 );
665 + //$q->set( 'nopaging', true );
689 666 } else {
690 667 $filter = new LP_Course_Filter();
691 668 $filter->only_fields = [ 'ID' ];
692 - $filter->limit = -1;
669 + $filter->limit = - 1;
693 670 $is_need_check_in_arr = false;
694 671 $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
695 672
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 + }
678 +
696 679 $q->set( 'posts_per_page', $limit );
697 680 // $q->set( 'cache_results', true ); // it default true
698 681
699 682 // Search courses by keyword
700 - // $q->set( 's', $_REQUEST['c_search'] ?? '' );
701 683 if ( ! empty( $_REQUEST['c_search'] ) ) {
702 684 $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
703 685 $is_need_check_in_arr = true;
704 686 }
@@ -707,9 +689,9 @@
707 689 if ( ! empty( $author_ids_str ) ) {
708 690 $q->set( 'author', $author_ids_str );
709 691 }
710 692
711 - // Meta query
693 + // Search course has price/free
712 694 $meta_query = [];
713 695 if ( isset( $_REQUEST['sort_by'] ) ) {
714 696 $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
715 697 if ( 'on_paid' === $sort_by ) {
@@ -721,25 +703,67 @@
721 703 }
722 704
723 705 if ( 'on_free' === $sort_by ) {
724 706 $meta_query[] = array(
725 - 'key' => '_lp_price',
726 - 'value' => 0,
727 - 'compare' => '=',
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 + ],
728 722 );
729 723 }
730 724 }
725 +
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 + }
737 +
731 738 $q->set( 'meta_query', $meta_query );
732 739 // End Meta query
733 740
734 - // Tax query
741 + // Search on Category
742 + $args_cat = lp_archive_skeleton_get_args();
735 743 $tax_query = [];
736 - $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['term_id'] ?? '' ) );
744 + $term_ids_str = LP_Helper::sanitize_params_submitted(
745 + urldecode( $_REQUEST['term_id'] ?? $args_cat['page_term_id_current'] ?? '' )
746 + );
737 747 if ( ! empty( $term_ids_str ) ) {
738 748 $term_ids = explode( ',', $term_ids_str );
739 749
740 750 $tax_query[] = array(
741 - 'taxonomy' => 'course_category',
751 + 'taxonomy' => 'course_category',
752 + 'field' => 'term_id',
753 + 'terms' => $term_ids,
754 + 'operator' => 'IN',
755 + 'include_children' => false,
756 + );
757 + }
758 +
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 );
763 +
764 + $tax_query[] = array(
765 + 'taxonomy' => 'course_tag',
742 766 'field' => 'term_id',
743 767 'terms' => $term_ids,
744 768 'operator' => 'IN',
745 769 );
@@ -779,9 +803,9 @@
779 803 $q->set( 'order', $order );
780 804 }
781 805
782 806 if ( $is_need_check_in_arr ) {
783 - $posts_in = LP_Course::get_courses( $filter );
807 + $posts_in = Courses::get_courses( $filter );
784 808 if ( ! empty( $posts_in ) ) {
785 809 $posts_in = LP_Database::get_values_by_key( $posts_in );
786 810 $q->set( 'post__in', $posts_in );
787 811 } else {
@@ -796,35 +820,21 @@
796 820 }
797 821
798 822 // Exclude item not assign
799 823 if ( $q->is_search() ) {
800 - // Exclude item not assign any course
801 - $course_item_types = learn_press_get_course_item_types();
802 - $list_ids_exclude = array();
803 -
804 - foreach ( $course_item_types as $item_type ) {
805 - $filter = new LP_Post_Type_Filter();
806 - $filter->post_type = $item_type;
807 - $exclude_item = LP_Course_DB::getInstance()->get_item_ids_unassigned( $filter );
808 - $exclude_item = LP_Course_DB::get_values_by_key( $exclude_item );
809 -
810 - $list_ids_exclude = array_merge( $list_ids_exclude, $exclude_item );
811 - }
812 -
813 - // Exclude question not assign any quiz
814 - $question_ids = LP_Question_DB::getInstance()->get_questions_not_assign_quiz();
815 - $question_ids = LP_Course_DB::get_values_by_key( $question_ids );
816 - $list_ids_exclude = array_merge( $list_ids_exclude, $question_ids );
817 -
818 - if ( ! empty( $list_ids_exclude ) ) {
819 - $q->set( 'post__not_in', $list_ids_exclude );
820 - }
821 -
822 824 return $q;
823 825 }
824 826
825 827 // Handle 404 if user are viewing course item directly.
826 828 $this->set_link_item_course_default_wp_to_page_404( $q );
829 +
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();
835 + }
836 + }
827 837 } catch ( Throwable $e ) {
828 838 error_log( $e->getMessage() );
829 839 }
830 840
@@ -836,16 +846,25 @@
836 846 * Example: http://example.com/lesson/slug-lesson
837 847 * Apply for user not admin, instructor, co-instructor
838 848 *
839 849 * @param WP_Query $q
850 + *
840 851 * @editor tungnx
841 852 * @since 3.2.7.5
842 853 */
843 854 public function set_link_item_course_default_wp_to_page_404( $q ) {
844 - $post_type_apply_404 = apply_filters( 'lp/page-controller/', array( LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, 'lp_assignment' ) );
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 + );
845 864
846 865 if ( ! isset( $q->query_vars['post_type'] ) || ! in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
847 - return $q;
866 + return;
848 867 }
849 868
850 869 try {
851 870 $flag_load_404 = true;
@@ -874,9 +893,9 @@
874 893
875 894 $flag_load_404 = apply_filters( 'learnpress/page/set-link-item-course-404', $flag_load_404, $post_author, $user );
876 895
877 896 if ( $flag_load_404 ) {
878 - learn_press_404_page();
897 + self::set_page_404();
879 898 }
880 899 } catch ( Throwable $e ) {
881 900 error_log( $e->getMessage() );
882 901 }
@@ -882,43 +901,8 @@
882 901 }
883 902 }
884 903
885 904 /**
886 - * @deprecated 4.1.6.9.2
887 - */
888 - /*public function the_content_callback( $content ) {
889 - if ( $this->_archive_contents ) {
890 - preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
891 - $this->_shortcode_exists = ! empty( $results );
892 - if ( $this->_shortcode_exists ) {
893 - $this->_shortcode_tag = $results[0];
894 - $content = str_replace( $this->_shortcode_tag, $this->_archive_contents, $content );
895 - } else {
896 - $content .= $this->_archive_contents;
897 - }
898 - }
899 -
900 - return $content;
901 - }*/
902 -
903 - /**
904 - * Check is page Become a teacher
905 - *
906 - * @return bool|mixed|void
907 - * @since 3.2.8
908 - * @author tungnx
909 - */
910 - public static function is_page_become_a_teacher() {
911 - $page_id = learn_press_get_page_id( 'become_a_teacher' );
912 -
913 - if ( $page_id && is_page( $page_id ) ) {
914 - return true;
915 - }
916 -
917 - return apply_filters( 'learnpress/is-page/become-a-teacher', false );
918 - }
919 -
920 - /**
921 905 * Get page current on frontend
922 906 *
923 907 * @return string
924 908 * @since 3.2.8
@@ -929,36 +913,275 @@
929 913 * @var WP_Query $wp_query
930 914 */
931 915 global $wp_query;
932 916
917 + // Course Builder page detection
918 + if ( self::is_page_course_builder() ) {
919 + return LP_PAGE_COURSE_BUILDER;
920 + }
921 +
933 922 if ( ! is_object( $wp_query ) || ! $wp_query->get_queried_object() ) {
934 923 return '';
935 924 }
936 925
937 - if ( learn_press_is_checkout() ) {
926 + if ( self::is_page_checkout() ) {
938 927 return LP_PAGE_CHECKOUT;
939 928 } elseif ( LP_Global::course_item_quiz() ) {
940 929 return LP_PAGE_QUIZ;
941 930 } elseif ( learn_press_is_course() && LP_Global::course_item() ) {
942 931 return LP_PAGE_SINGLE_COURSE_CURRICULUM;
943 - } elseif ( learn_press_is_courses() ) {
932 + } elseif ( self::is_page_courses() ) {
944 933 return LP_PAGE_COURSES;
945 934 } elseif ( learn_press_is_course() ) {
946 935 return LP_PAGE_SINGLE_COURSE;
947 936 } elseif ( self::is_page_become_a_teacher() ) {
948 937 return LP_PAGE_BECOME_A_TEACHER;
949 - } elseif ( learn_press_is_profile() ) {
938 + } elseif ( self::is_page_profile() ) {
950 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;
951 944 } else {
952 945 return apply_filters( 'learnpress/page/current', '' );
953 946 }
954 947 }
955 948
956 - public static function instance() {
957 - if ( is_admin() ) {
958 - return null;
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;
959 960 }
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;
1028 + } else {
1029 + $flag = false;
1030 + }
1031 + }
1032 +
1033 + return $flag;
1034 + }
1035 +
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 + /**
1098 + * Check is page Become a teacher
1099 + *
1100 + * @return bool
1101 + * @since 3.2.8
1102 + * @author tungnx
1103 + */
1104 + public static function is_page_become_a_teacher(): bool {
1105 + return self::page_is( 'become_a_teacher' );
1106 + }
1107 +
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() ) ) {
1118 + return true;
1119 + }
1120 +
1121 + return false;
1122 + }
1123 +
1124 + /**
1125 + * Redirect admin to course builder if hide instructor access admin screen
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 + *
1165 + * @return string
1166 + * @since 4.2.7.8
1167 + * @version 1.0.0
1168 + */
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 );
1174 + }
1175 +
1176 + if ( $no_cache ) {
1177 + $page_link = LP_Helper::get_link_no_cache( $page_link );
1178 + }
1179 +
1180 + return $page_link;
1181 + }
1182 +
1183 + public static function instance() {
961 1184 if ( ! self::$_instance ) {
962 1185 self::$_instance = new self();
963 1186 }
964 1187
@@ -973,8 +1196,11 @@
973 1196 * @since 3.0.0
974 1197 * @deprecated 4.1.7.3
975 1198 */
976 1199 public function learn_press_edit_admin_bar() {
1200 + _deprecated_function( __METHOD__, '4.1.7.3' );
1201 + return;
1202 +
977 1203 global $wp_admin_bar;
978 1204
979 1205 $current_user = wp_get_current_user();
980 1206
@@ -984,8 +1210,9 @@
984 1210
985 1211 $page_profile_id = learn_press_get_page_id( 'profile' );
986 1212 if ( $page_profile_id && get_post_status( $page_profile_id ) != 'trash' ) {
987 1213 $user_id = $current_user->ID;
1214 + $profile = LP_Profile::instance( $user_id );
988 1215
989 1216 $wp_admin_bar->add_menu(
990 1217 array(
991 1218 'id' => 'course_profile',
@@ -990,9 +1217,9 @@
990 1217 array(
991 1218 'id' => 'course_profile',
992 1219 'parent' => 'user-actions',
993 1220 'title' => get_the_title( $page_profile_id ),
994 - 'href' => learn_press_user_profile_link( $user_id, false ),
1221 + 'href' => $profile->get_tab_link(),
995 1222 )
996 1223 );
997 1224 }
998 1225 }
@@ -997,60 +1224,102 @@
997 1224 }
998 1225 }
999 1226
1000 1227 /**
1001 - * Check notify papal call when done.
1228 + * Set again HTTP_X_WP_NONCE when cache make 403 error.
1002 1229 *
1003 - * Set in param notify_url on @see LP_Gateway_Paypal::get_paypal_args()
1230 + * @param $send_no_cache_headers
1231 + *
1232 + * @return mixed
1233 + * @since 4.1.7
1234 + * @version 1.0.0
1004 1235 */
1005 - public function check_webhook_paypal_ipn() {
1006 - //error_log( 'xxx:' . json_encode( $_POST, JSON_UNESCAPED_UNICODE ) );
1007 -
1008 - // Paypal payment done
1009 - if ( ! isset( $_GET['paypal_notify'] ) ) {
1010 - return;
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;
1011 1240 }
1012 1241
1013 - if ( ! isset( $_POST['ipn_track_id'] ) ) {
1014 - return;
1015 - }
1242 + return $send_no_cache_headers;
1243 + }
1016 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 {
1017 1256 try {
1018 - $paypal = new LP_Gateway_Paypal();
1019 - $verify = $paypal->validate_ipn();
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 + }
1020 1261
1021 - if ( $verify ) {
1022 - if ( isset( $_POST['custom'] ) ) {
1023 - $data_order = json_decode( LP_Helper::sanitize_params_submitted( $_POST['custom'] ) );
1024 -
1025 - if ( json_last_error() === JSON_ERROR_NONE ) {
1026 - $order_id = $data_order->order_id;
1027 - $lp_order = learn_press_get_order( $order_id );
1028 - $lp_order->update_status( LP_ORDER_COMPLETED );
1029 - }
1030 - }
1031 - }
1262 + return $link;
1032 1263 } catch ( Throwable $e ) {
1033 1264 error_log( $e->getMessage() );
1034 1265 }
1266 +
1267 + return $link;
1035 1268 }
1036 1269
1037 1270 /**
1038 - * Set again HTTP_X_WP_NONCE when cache make 403 error.
1271 + * Set menu active for page courses.
1039 1272 *
1040 - * @param $send_no_cache_headers
1273 + * @param $menu_items
1041 1274 *
1042 1275 * @return mixed
1043 - * @since 4.1.7
1044 - * @version 1.0.0
1045 1276 */
1046 - public function check_x_wp_nonce_cache( $send_no_cache_headers ) {
1047 - if ( ! $send_no_cache_headers && ! is_admin() && $_SERVER['REQUEST_METHOD'] == 'GET' && LP_Helper::isRestApiLP() ) {
1048 - $nonce = wp_create_nonce( 'wp_rest' );
1049 - $_SERVER['HTTP_X_WP_NONCE'] = $nonce;
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 + }
1050 1310 }
1051 1311
1052 - return $send_no_cache_headers;
1312 + return $menu_items;
1053 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 + }
1054 1325 }
1055 -
1056 -return LP_Page_Controller::instance();