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 +654 -392 4.1.7.3.24.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,23 +213,21 @@
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 221 */
225 222 public function set_title_pages( $title = '' ): string {
226 - global $wp_query;
227 223 $flag_title_course = false;
224 + $user_id = get_current_user_id();
228 225
229 - $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 );
230 227
231 - // Set title course archive page
232 - if ( ! empty( $course_archive_page_id ) && $wp_query->post &&
233 - $course_archive_page_id == $wp_query->post->ID ) {
234 - $title = get_the_title( $course_archive_page_id );
235 - $flag_title_course = true;
236 - } elseif ( learn_press_is_course() ) {
228 + // Set title single course.
229 + if ( learn_press_is_course() ) {
237 230 $item = LP_Global::course_item();
238 231 if ( $item ) {
239 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
240 233
@@ -239,21 +232,33 @@
239 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
240 233
241 234 $flag_title_course = true;
242 235 }
243 - } elseif ( learn_press_is_courses() ) {
244 - if ( learn_press_is_search() ) {
236 + } elseif ( LP_Page_Controller::is_page_courses() ) { // Set title course archive page.
237 + if ( isset( $_GET['c_search'] ) ) {
245 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 + }
246 247 } else {
247 - $title = __( 'Courses', 'learnpress' );
248 + $title = $course_archive_page_id ? get_the_title( $course_archive_page_id ) : __( 'Courses', 'learnpress' );
248 249 }
249 250
250 251 $flag_title_course = true;
251 - } elseif ( learn_press_is_profile() ) {
252 - $profile = LP_Profile::instance();
253 - $tab_slug = $profile->get_current_tab();
254 - $tab = $profile->get_tab_at( $tab_slug );
255 - $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 + }
256 261
257 262 if ( $page_id ) {
258 263 $page_title = get_the_title( $page_id );
259 264 } else {
@@ -258,9 +263,10 @@
258 263 $page_title = get_the_title( $page_id );
259 264 } else {
260 265 $page_title = '';
261 266 }
262 - if ( $tab ) {
267 +
268 + if ( $tab instanceof LP_Profile_Tab ) {
263 269 $title = join(
264 270 ' ',
265 271 apply_filters(
266 272 'learn-press/document-profile-title-parts',
@@ -266,12 +272,14 @@
266 272 'learn-press/document-profile-title-parts',
267 273 array(
268 274 $page_title,
269 275 '&rarr;',
270 - $tab['title'],
276 + $tab->get( 'title' ),
271 277 )
272 278 )
273 279 );
280 + } else {
281 + $title = $page_title;
274 282 }
275 283
276 284 $flag_title_course = true;
277 285 }
@@ -279,8 +287,12 @@
279 287 if ( $flag_title_course ) {
280 288 $title .= ' - ' . get_bloginfo( 'name', 'display' );
281 289 }
282 290
291 + if ( ! is_string( $title ) ) {
292 + $title = get_bloginfo( 'name', 'display' );
293 + }
294 +
283 295 return apply_filters( 'learn-press/title-page', $title );
284 296 }
285 297
286 298 /**
@@ -306,56 +318,19 @@
306 318
307 319 return $desc;
308 320 }
309 321
310 - public function check_pages( $template ) {
311 - if ( learn_press_is_checkout() ) {
312 - $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
313 -
314 - if ( ! $available_gateways ) {
315 - learn_press_add_message( __( 'No payment method is available.', 'learnpress' ), 'error' );
316 - }
317 - } else {
318 - global $wp_query;
319 -
320 - $logout_slug = learn_press_profile_logout_slug();
321 -
322 - if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
323 - wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
324 - exit;
325 - }
326 - }
327 -
328 - return $template;
329 - }
330 -
331 322 /**
332 - * Auto inserting a registered shortcode to a specific page
333 - * if that page is viewing in single mode.
334 - *
335 - * @param string $template
336 - *
337 - * @return string;
338 - * @since 3.3.0
323 + * Handle logout
339 324 */
340 - public function auto_shortcode( $template ) {
341 - global $post;
342 - $the_post = $post;
343 - if ( $the_post && is_page( $the_post->ID ) ) {
325 + public function logout( $template ) {
326 + global $wp_query;
344 327
345 - // Filter here to insert the shortcode
346 - $auto_shortcodes = apply_filters( 'learn-press/auto-shortcode-pages', array() );
328 + $logout_slug = learn_press_profile_logout_slug();
347 329
348 - if ( ! empty( $auto_shortcodes[ $the_post->ID ] ) ) {
349 - $shortcode_tag = $auto_shortcodes[ $the_post->ID ];
350 -
351 - preg_match( '/\[' . $shortcode_tag . '\s?(.*)\]/', $the_post->post_content, $results );
352 -
353 - if ( empty( $results ) ) {
354 - $content = $the_post->post_content . "[$shortcode_tag]";
355 - $the_post->post_content = $content;
356 - }
357 - }
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;
358 333 }
359 334
360 335 return $template;
361 336 }
@@ -376,8 +351,12 @@
376 351 * @var LP_Course $lp_course
377 352 * @var LP_Course_Item|LP_Quiz|LP_Lesson $lp_course_item
378 353 */
379 354 global $wp, $wp_query, $lp_course_item;
355 + $vars = $wp->query_vars;
356 + if ( empty( $vars['course-item'] ) ) {
357 + return $post;
358 + }
380 359
381 360 if ( LP_COURSE_CPT !== $post->post_type ) {
382 361 return $post;
383 362 }
@@ -387,8 +366,20 @@
387 366 return $post;
388 367 }
389 368
390 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 + /**
391 382 * @deprecated v4.1.6.1 LearnPress::instance()->global['course'], $GLOBALS['course']
392 383 * Some theme still use: global $course; LearnPress::instance()->global['course']
393 384 */
394 385 //LearnPress::instance()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
@@ -393,18 +384,12 @@
393 384 */
394 385 //LearnPress::instance()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
395 386 LearnPress::instance()->global['course'] = $GLOBALS['course'] = $course;
396 387
397 - if ( wp_verify_nonce( LP_Request::get( 'preview' ), 'preview-' . $post->ID ) ) {
388 + if ( wp_verify_nonce( LP_Request::get_param( 'preview' ), 'preview-' . $post->ID ) ) {
398 389 $GLOBALS['preview_course'] = $post->ID;
399 390 }
400 391
401 - $vars = $wp->query_vars;
402 -
403 - if ( empty( $vars['course-item'] ) ) {
404 - return $post;
405 - }
406 -
407 392 if ( ! $wp_query->is_main_query() ) {
408 393 return $post;
409 394 }
410 395
@@ -411,14 +396,10 @@
411 396 try {
412 397 $user = learn_press_get_current_user();
413 398
414 399 // If item name is set in query vars
415 - if ( ! is_numeric( $vars['course-item'] ) ) {
416 - $item_type = $vars['item-type'];
417 - $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
418 - } else {
419 - $post_item = get_post( absint( $vars['course-item'] ) );
420 - }
400 + $item_type = $vars['item-type'];
401 + $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
421 402
422 403 if ( ! $post_item ) {
423 404 return $post;
424 405 }
@@ -430,29 +411,15 @@
430 411 }
431 412
432 413 // Set item viewing
433 414 $user->set_viewing_item( $lp_course_item );
434 - } catch ( Exception $ex ) {
435 - learn_press_add_message( $ex->getMessage(), 'error' );
415 + } catch ( Throwable $e ) {
416 + error_log( $e->getMessage() );
436 417 }
437 418
438 419 return $post;
439 420 }
440 421
441 - /**
442 - * Set page 404
443 - *
444 - * @return mixed
445 - * @editor tungnx
446 - * @reason not use
447 - * @deprecated 4.0.0
448 - */
449 - /*
450 - public function set_404( $is_404 ) {
451 - global $wp_query;
452 - $wp_query->is_404 = $this->_is_404 = (bool) $is_404;
453 - }*/
454 -
455 422 public function is_404() {
456 423 return apply_filters( 'learn-press/query/404', $this->_is_404 );
457 424 }
458 425
@@ -476,17 +443,23 @@
476 443 }
477 444
478 445 /**
479 446 * @return bool
447 + * @deprecated v4.2.7.6
480 448 */
481 449 protected function _is_archive() {
450 + _deprecated_function( __METHOD__, '4.1.7.3' );
451 + return false;
482 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();
483 453 }
484 454
485 455 /**
486 456 * @return bool
457 + * @deprecated v4.2.7.6
487 458 */
488 459 protected function _is_single() {
460 + _deprecated_function( __METHOD__, '4.1.7.3' );
461 + return false;
489 462 return learn_press_is_course() && is_single();
490 463 }
491 464
492 465 /**
@@ -496,8 +469,11 @@
496 469 *
497 470 * @return bool|string
498 471 */
499 472 public function template_loader( $template ) {
473 + if ( wp_is_block_theme() ) {
474 + return $template;
475 + }
500 476
501 477 if ( is_embed() ) {
502 478 return $template;
503 479 }
@@ -526,8 +502,18 @@
526 502 return $template;
527 503 }
528 504
529 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 + /**
530 516 * Get the default filename for a template.
531 517 *
532 518 * @return string
533 519 * @since 4.0.0
@@ -533,40 +519,59 @@
533 519 * @since 4.0.0
534 520 */
535 521 private function get_page_template() {
536 522 $page_template = '';
523 + $object = get_queried_object();
537 524
538 - if ( is_singular( LP_COURSE_CPT ) ) {
539 - 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
540 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';
541 544 }
542 545
543 - if ( $this->_is_single() ) {
544 - global $post;
545 - setup_postdata( $post );
546 + // Old single course layout.
547 + //$page_template = 'single-course.php';
546 548
547 - $course_item = LP_Global::course_item();
548 - if ( $course_item && ! self::has_block_template( 'content-single-course-item' ) ) {
549 - $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';
550 559 }
551 560 }
552 561 } elseif ( learn_press_is_course_taxonomy() ) {
553 - $object = get_queried_object();
554 -
555 562 if ( is_tax( 'course_category' ) || is_tax( 'course_tag' ) ) {
556 563 $page_template = 'taxonomy-' . $object->taxonomy . '.php';
557 564
558 - if ( self::has_block_template( 'taxonomy-' . $object->taxonomy ) ) {
559 - $page_template = '';
560 - } 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 ) ) ) {
561 566 $page_template = 'archive-course.php';
562 567 }
563 - } elseif ( ! self::has_block_template( 'archive-course' ) ) {
568 + } else {
564 569 $page_template = 'archive-course.php';
565 570 }
566 - } 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() ) {
567 572 $page_template = 'archive-course.php';
568 - } elseif ( learn_press_is_checkout() && ! self::has_block_template( 'page-lp_checkout' ) ) {
573 + } elseif ( learn_press_is_checkout() ) {
569 574 $page_template = 'pages/checkout.php';
570 575 }
571 576
572 577 return apply_filters( 'learn-press/page-template', $page_template );
@@ -587,9 +592,9 @@
587 592 }
588 593 }
589 594 }
590 595
591 - if ( is_singular( LP_COURSE_CPT ) ) {
596 + /*if ( is_singular( LP_COURSE_CPT ) ) {
592 597 $object = get_queried_object();
593 598 $name_decoded = urldecode( $object->post_name );
594 599
595 600 if ( $name_decoded !== $object->post_name ) {
@@ -596,53 +601,25 @@
596 601 $templates[] = "single-course-$name_decoded.php";
597 602 }
598 603
599 604 $templates[] = "single-product-$object->post_name.php";
600 - }
605 + }*/
601 606
602 607 if ( learn_press_is_course_taxonomy() ) {
603 608 $object = get_queried_object();
604 609 $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
605 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
610 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
606 611 $templates[] = 'taxonomy-' . $object->taxonomy . '.php';
607 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '.php';
612 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '.php';
608 613 }
609 614
610 615 $templates[] = $default_template;
611 - $templates[] = learn_press_template_path( true ) . $default_template;
616 + $templates[] = learn_press_template_path() . '/' . $default_template;
612 617
613 618 return array_unique( $templates );
614 619 }
615 620
616 621 /**
617 - * Filter to allow search more templates in theme for wp page template hierarchy.
618 - * Theme twentytwenty used 'singular.php' instead of 'page.php'
619 - *
620 - * @param array $templates
621 - *
622 - * @return array
623 - * @since 3.x.x
624 - * @deprecated 4.1.6.9.2
625 - */
626 - /*public function page_template_hierarchy( $templates ) {
627 - $templates = array_merge( $templates, array( 'singular.php' ) );
628 -
629 - return $templates;
630 - }*/
631 -
632 - /**
633 - * Archive course content.
634 - *
635 - * @return false|string
636 - */
637 - public function archive_content() {
638 - ob_start();
639 - learn_press_get_template( 'content-archive-course.php' );
640 -
641 - return ob_get_clean();
642 - }
643 -
644 - /**
645 622 * @param $title
646 623 *
647 624 * @return mixed
648 625 */
@@ -661,11 +638,11 @@
661 638 * @param $q WP_Query
662 639 *
663 640 * @return WP_Query
664 641 * @editor tungnx
642 + * @throws Exception
643 + * @version 4.1.3
665 644 * @since 3.0.0
666 - * @version 4.1.3
667 - * @throws Exception
668 645 */
669 646 public function pre_get_posts( WP_Query $q ): WP_Query {
670 647 // Affect only the main query and not in admin
671 648 if ( ! $q->is_main_query() && ! is_admin() ) {
@@ -672,11 +649,11 @@
672 649 return $q;
673 650 }
674 651
675 652 try {
676 - if ( LP_Page_Controller::page_current() === LP_PAGE_COURSES ) {
677 - if ( ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses() ) ) {
678 - 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() ) {
679 656 /**
680 657 * If page is archive course - query set posts_per_page = 1
681 658 * For fastest - because when page loaded - call API to load list courses
682 659 *
@@ -682,22 +659,28 @@
682 659 *
683 660 * Current, apply only for LP, not apply for theme Thimpress, because theme override
684 661 */
685 662 $q->set( 'posts_per_page', 1 );
686 - $q->set( 'posts_per_archive_page', 1 );
687 - $q->set( 'nopaging', true );
663 + $q->set( 'suppress_filters', true );
664 + //$q->set( 'posts_per_archive_page', 1 );
665 + //$q->set( 'nopaging', true );
688 666 } else {
689 667 $filter = new LP_Course_Filter();
690 668 $filter->only_fields = [ 'ID' ];
691 - $filter->limit = -1;
669 + $filter->limit = - 1;
692 670 $is_need_check_in_arr = false;
693 671 $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
694 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 +
695 679 $q->set( 'posts_per_page', $limit );
696 680 // $q->set( 'cache_results', true ); // it default true
697 681
698 682 // Search courses by keyword
699 - // $q->set( 's', $_REQUEST['c_search'] ?? '' );
700 683 if ( ! empty( $_REQUEST['c_search'] ) ) {
701 684 $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
702 685 $is_need_check_in_arr = true;
703 686 }
@@ -706,9 +689,9 @@
706 689 if ( ! empty( $author_ids_str ) ) {
707 690 $q->set( 'author', $author_ids_str );
708 691 }
709 692
710 - // Meta query
693 + // Search course has price/free
711 694 $meta_query = [];
712 695 if ( isset( $_REQUEST['sort_by'] ) ) {
713 696 $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
714 697 if ( 'on_paid' === $sort_by ) {
@@ -720,25 +703,67 @@
720 703 }
721 704
722 705 if ( 'on_free' === $sort_by ) {
723 706 $meta_query[] = array(
724 - 'key' => '_lp_price',
725 - 'value' => 0,
726 - '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 + ],
727 722 );
728 723 }
729 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 +
730 738 $q->set( 'meta_query', $meta_query );
731 739 // End Meta query
732 740
733 - // Tax query
741 + // Search on Category
742 + $args_cat = lp_archive_skeleton_get_args();
734 743 $tax_query = [];
735 - $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 + );
736 747 if ( ! empty( $term_ids_str ) ) {
737 748 $term_ids = explode( ',', $term_ids_str );
738 749
739 750 $tax_query[] = array(
740 - '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',
741 766 'field' => 'term_id',
742 767 'terms' => $term_ids,
743 768 'operator' => 'IN',
744 769 );
@@ -778,9 +803,9 @@
778 803 $q->set( 'order', $order );
779 804 }
780 805
781 806 if ( $is_need_check_in_arr ) {
782 - $posts_in = LP_Course::get_courses( $filter );
807 + $posts_in = Courses::get_courses( $filter );
783 808 if ( ! empty( $posts_in ) ) {
784 809 $posts_in = LP_Database::get_values_by_key( $posts_in );
785 810 $q->set( 'post__in', $posts_in );
786 811 } else {
@@ -795,35 +820,21 @@
795 820 }
796 821
797 822 // Exclude item not assign
798 823 if ( $q->is_search() ) {
799 - // Exclude item not assign any course
800 - $course_item_types = learn_press_get_course_item_types();
801 - $list_ids_exclude = array();
802 -
803 - foreach ( $course_item_types as $item_type ) {
804 - $filter = new LP_Post_Type_Filter();
805 - $filter->post_type = $item_type;
806 - $exclude_item = LP_Course_DB::getInstance()->get_item_ids_unassigned( $filter );
807 - $exclude_item = LP_Course_DB::get_values_by_key( $exclude_item );
808 -
809 - $list_ids_exclude = array_merge( $list_ids_exclude, $exclude_item );
810 - }
811 -
812 - // Exclude question not assign any quiz
813 - $question_ids = LP_Question_DB::getInstance()->get_questions_not_assign_quiz();
814 - $question_ids = LP_Course_DB::get_values_by_key( $question_ids );
815 - $list_ids_exclude = array_merge( $list_ids_exclude, $question_ids );
816 -
817 - if ( ! empty( $list_ids_exclude ) ) {
818 - $q->set( 'post__not_in', $list_ids_exclude );
819 - }
820 -
821 824 return $q;
822 825 }
823 826
824 827 // Handle 404 if user are viewing course item directly.
825 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 + }
826 837 } catch ( Throwable $e ) {
827 838 error_log( $e->getMessage() );
828 839 }
829 840
@@ -835,16 +846,25 @@
835 846 * Example: http://example.com/lesson/slug-lesson
836 847 * Apply for user not admin, instructor, co-instructor
837 848 *
838 849 * @param WP_Query $q
850 + *
839 851 * @editor tungnx
840 852 * @since 3.2.7.5
841 853 */
842 854 public function set_link_item_course_default_wp_to_page_404( $q ) {
843 - $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 + );
844 864
845 865 if ( ! isset( $q->query_vars['post_type'] ) || ! in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
846 - return $q;
866 + return;
847 867 }
848 868
849 869 try {
850 870 $flag_load_404 = true;
@@ -873,9 +893,9 @@
873 893
874 894 $flag_load_404 = apply_filters( 'learnpress/page/set-link-item-course-404', $flag_load_404, $post_author, $user );
875 895
876 896 if ( $flag_load_404 ) {
877 - learn_press_404_page();
897 + self::set_page_404();
878 898 }
879 899 } catch ( Throwable $e ) {
880 900 error_log( $e->getMessage() );
881 901 }
@@ -881,43 +901,8 @@
881 901 }
882 902 }
883 903
884 904 /**
885 - * @deprecated 4.1.6.9.2
886 - */
887 - /*public function the_content_callback( $content ) {
888 - if ( $this->_archive_contents ) {
889 - preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
890 - $this->_shortcode_exists = ! empty( $results );
891 - if ( $this->_shortcode_exists ) {
892 - $this->_shortcode_tag = $results[0];
893 - $content = str_replace( $this->_shortcode_tag, $this->_archive_contents, $content );
894 - } else {
895 - $content .= $this->_archive_contents;
896 - }
897 - }
898 -
899 - return $content;
900 - }*/
901 -
902 - /**
903 - * Check is page Become a teacher
904 - *
905 - * @return bool|mixed|void
906 - * @since 3.2.8
907 - * @author tungnx
908 - */
909 - public static function is_page_become_a_teacher() {
910 - $page_id = learn_press_get_page_id( 'become_a_teacher' );
911 -
912 - if ( $page_id && is_page( $page_id ) ) {
913 - return true;
914 - }
915 -
916 - return apply_filters( 'learnpress/is-page/become-a-teacher', false );
917 - }
918 -
919 - /**
920 905 * Get page current on frontend
921 906 *
922 907 * @return string
923 908 * @since 3.2.8
@@ -928,36 +913,275 @@
928 913 * @var WP_Query $wp_query
929 914 */
930 915 global $wp_query;
931 916
917 + // Course Builder page detection
918 + if ( self::is_page_course_builder() ) {
919 + return LP_PAGE_COURSE_BUILDER;
920 + }
921 +
932 922 if ( ! is_object( $wp_query ) || ! $wp_query->get_queried_object() ) {
933 923 return '';
934 924 }
935 925
936 - if ( learn_press_is_checkout() ) {
926 + if ( self::is_page_checkout() ) {
937 927 return LP_PAGE_CHECKOUT;
938 928 } elseif ( LP_Global::course_item_quiz() ) {
939 929 return LP_PAGE_QUIZ;
940 930 } elseif ( learn_press_is_course() && LP_Global::course_item() ) {
941 931 return LP_PAGE_SINGLE_COURSE_CURRICULUM;
942 - } elseif ( learn_press_is_courses() ) {
932 + } elseif ( self::is_page_courses() ) {
943 933 return LP_PAGE_COURSES;
944 934 } elseif ( learn_press_is_course() ) {
945 935 return LP_PAGE_SINGLE_COURSE;
946 936 } elseif ( self::is_page_become_a_teacher() ) {
947 937 return LP_PAGE_BECOME_A_TEACHER;
948 - } elseif ( learn_press_is_profile() ) {
938 + } elseif ( self::is_page_profile() ) {
949 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;
950 944 } else {
951 945 return apply_filters( 'learnpress/page/current', '' );
952 946 }
953 947 }
954 948
955 - public static function instance() {
956 - if ( is_admin() ) {
957 - 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;
958 960 }
959 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() {
960 1184 if ( ! self::$_instance ) {
961 1185 self::$_instance = new self();
962 1186 }
963 1187
@@ -972,8 +1196,11 @@
972 1196 * @since 3.0.0
973 1197 * @deprecated 4.1.7.3
974 1198 */
975 1199 public function learn_press_edit_admin_bar() {
1200 + _deprecated_function( __METHOD__, '4.1.7.3' );
1201 + return;
1202 +
976 1203 global $wp_admin_bar;
977 1204
978 1205 $current_user = wp_get_current_user();
979 1206
@@ -983,8 +1210,9 @@
983 1210
984 1211 $page_profile_id = learn_press_get_page_id( 'profile' );
985 1212 if ( $page_profile_id && get_post_status( $page_profile_id ) != 'trash' ) {
986 1213 $user_id = $current_user->ID;
1214 + $profile = LP_Profile::instance( $user_id );
987 1215
988 1216 $wp_admin_bar->add_menu(
989 1217 array(
990 1218 'id' => 'course_profile',
@@ -989,9 +1217,9 @@
989 1217 array(
990 1218 'id' => 'course_profile',
991 1219 'parent' => 'user-actions',
992 1220 'title' => get_the_title( $page_profile_id ),
993 - 'href' => learn_press_user_profile_link( $user_id, false ),
1221 + 'href' => $profile->get_tab_link(),
994 1222 )
995 1223 );
996 1224 }
997 1225 }
@@ -996,68 +1224,102 @@
996 1224 }
997 1225 }
998 1226
999 1227 /**
1000 - * Check notify papal call when done.
1228 + * Set again HTTP_X_WP_NONCE when cache make 403 error.
1001 1229 *
1002 - * 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
1003 1235 */
1004 - public function check_webhook_paypal_ipn() {
1005 - // Start session, code temporary, will rewrite on hook init.
1006 - if ( ! session_id() ) {
1007 - session_start();
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;
1008 1240 }
1009 - // End - tungnx
1010 1241
1011 - //error_log( 'xxx:' . json_encode( $_POST, JSON_UNESCAPED_UNICODE ) );
1242 + return $send_no_cache_headers;
1243 + }
1012 1244
1013 - // Paypal payment done
1014 - if ( ! isset( $_GET['paypal_notify'] ) ) {
1015 - return;
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() );
1016 1265 }
1017 1266
1018 - if ( ! isset( $_POST['ipn_track_id'] ) ) {
1019 - return;
1020 - }
1267 + return $link;
1268 + }
1021 1269
1022 - try {
1023 - $paypal = new LP_Gateway_Paypal();
1024 - $verify = $paypal->validate_ipn();
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' );
1025 1280
1026 - if ( $verify ) {
1027 - if ( isset( $_POST['custom'] ) ) {
1028 - $data_order = json_decode( LP_Helper::sanitize_params_submitted( $_POST['custom'] ) );
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;
1029 1285
1030 - if ( json_last_error() === JSON_ERROR_NONE ) {
1031 - $order_id = $data_order->order_id;
1286 + // Unset active class for blog page.
1287 + if ( $page_for_posts === $menu_id ) {
1288 + $menu_item->current = false;
1032 1289
1033 - $lp_order = learn_press_get_order( $order_id );
1034 - $lp_order->set_status( 'completed' );
1035 - $lp_order->save();
1290 + if ( in_array( 'current_page_parent', $classes, true ) ) {
1291 + unset( $classes[ array_search( 'current_page_parent', $classes, true ) ] );
1036 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';
1037 1305 }
1306 +
1307 + $menu_item->classes = array_unique( $classes );
1308 + $menu_items[ $key ] = $menu_item;
1038 1309 }
1039 - } catch ( Throwable $e ) {
1040 - error_log( $e->getMessage() );
1041 1310 }
1311 +
1312 + return $menu_items;
1042 1313 }
1043 1314
1044 1315 /**
1045 - * Set again HTTP_X_WP_NONCE when cache make 403 error.
1316 + * Set Page viewing to 404
1046 1317 *
1047 - * @param $send_no_cache_headers
1048 - *
1049 - * @return mixed
1050 - * @since 4.1.7
1051 - * @version 1.0.0
1318 + * @return void
1052 1319 */
1053 - public function check_x_wp_nonce_cache( $send_no_cache_headers ) {
1054 - if ( ! $send_no_cache_headers && ! is_admin() && $_SERVER['REQUEST_METHOD'] == 'GET' && LP_Helper::isRestApiLP() ) {
1055 - $nonce = wp_create_nonce( 'wp_rest' );
1056 - $_SERVER['HTTP_X_WP_NONCE'] = $nonce;
1057 - }
1058 -
1059 - return $send_no_cache_headers;
1320 + public static function set_page_404() {
1321 + global $wp_query;
1322 + $wp_query->set_404();
1323 + status_header( 404 );
1060 1324 }
1061 1325 }
1062 -
1063 -return LP_Page_Controller::instance();