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 +671 -386 4.1.7.14.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,76 +34,142 @@
28 34 /**
29 35 * LP_Page_Controller constructor.
30 36 */
31 37 protected function __construct() {
32 - add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), -1 );
33 - add_filter( 'template_include', array( $this, 'template_loader' ), 10 );
34 - add_filter( 'template_include', array( $this, 'check_pages' ), 30 );
35 - add_filter( 'template_include', array( $this, 'auto_shortcode' ), 50 );
38 + // Set link course, item course.
39 + add_filter( 'post_type_link', array( $this, 'post_type_link' ), 10, 2 );
36 40
37 - add_filter( 'the_post', array( $this, 'setup_data_for_item_course' ) );
38 - 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 + }
39 46
40 - add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
41 - add_filter( 'pre_get_document_title', array( $this, 'set_title_pages' ), 20, 1 );
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 + }
42 68
43 - // Yoast seo
44 - add_filter( 'wpseo_opengraph_desc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
45 - add_filter( 'wpseo_metadesc', array( $this, 'lp_desc_item_yoast_seo' ), 11, 1 );
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 ';
46 72
47 - // edit link item course when form search default wp
48 - 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 );
49 83
50 - // Set link profile to admin menu
51 - 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 );
52 86
53 - // Web hook detected PayPal request.
54 - add_action( 'init', [ $this, 'check_webhook_paypal_ipn' ] );
55 - // Set again x-wp-nonce on header when has cache with not login.
56 - add_filter( 'rest_send_nocache_headers', array( $this, 'check_x_wp_nonce_cache' ) );
57 - }
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 );
58 89
59 - /**
60 - * Check notify papal call when done.
61 - *
62 - * Set in param notify_url on @see LP_Gateway_Paypal::get_paypal_args()
63 - */
64 - public function check_webhook_paypal_ipn() {
65 - //error_log( 'xxx:' . json_encode( $_POST, JSON_UNESCAPED_UNICODE ) );
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 );
66 93
67 - // Paypal payment done
68 - if ( ! isset( $_GET['paypal_notify'] ) ) {
69 - return;
70 - }
94 + // Set link profile to admin menu
95 + //add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
71 96
72 - if ( ! isset( $_POST['ipn_track_id'] ) ) {
73 - return;
74 - }
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' ) );
75 99
76 - try {
77 - $paypal = new LP_Gateway_Paypal();
78 - $verify = $paypal->validate_ipn();
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 + }
79 111
80 - if ( $verify ) {
81 - if ( isset( $_POST['custom'] ) ) {
82 - $data_order = json_decode( LP_Helper::sanitize_params_submitted( $_POST['custom'] ) );
112 + return $canonical_url;
113 + }
114 + );
115 + }
83 116
84 - if ( json_last_error() === JSON_ERROR_NONE ) {
85 - $order_id = $data_order->order_id;
86 -
87 - $lp_order = learn_press_get_order( $order_id );
88 - $lp_order->set_status( 'completed' );
89 - $lp_order->save();
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 ] );
90 126 }
91 127 }
128 +
129 + return $post_types;
92 130 }
93 - } catch ( Throwable $e ) {
94 - error_log( $e->getMessage() );
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 + );*/
152 + }
153 +
154 + /**
155 + * Set link archive course.
156 + *
157 + * @param string $link
158 + * @param string $post_type
159 + *
160 + * @return string
161 + */
162 + public function link_archive_course( string $link, string $post_type ): string {
163 + if ( $post_type == LP_COURSE_CPT && learn_press_get_page_id( 'courses' ) ) {
164 + $link = learn_press_get_page_link( 'courses' );
95 165 }
166 +
167 + return $link;
96 168 }
97 169
98 170 /**
99 - * Set link item course when form search default wp
171 + * Set link course, item course
100 172 *
101 173 * @param string $post_link
102 174 * @param object $post
103 175 */
@@ -102,20 +174,19 @@
102 174 * @param object $post
103 175 */
104 176 public function post_type_link( $post_link, $post ) {
105 177 // Set item's course permalink
106 - $course_item_types = learn_press_get_course_item_types();
178 + $course_item_types = CourseModel::item_types_support();
107 179 $item_id = $post->ID;
108 180
109 - 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() ) {
110 183 $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id );
111 -
112 184 if ( ! $section_id ) {
113 185 return $post_link;
114 186 }
115 187
116 188 $course_id = LP_Section_DB::getInstance()->get_course_id_by_section( $section_id );
117 -
118 189 if ( ! $course_id ) {
119 190 return $post_link;
120 191 }
121 192
@@ -125,113 +196,15 @@
125 196 }
126 197
127 198 $post_link = $course->get_item_link( $item_id );
128 199 } elseif ( LP_COURSE_CPT === $post->post_type ) {
129 - // Abort early if the placeholder rewrite tag isn't in the generated URL
130 - if ( false === strpos( $post_link, '%' ) ) {
131 - return $post_link;
132 - }
133 -
134 - // Get the custom taxonomy terms in use by this post
135 - $terms = get_the_terms( $post->ID, 'course_category' );
136 -
137 - if ( ! empty( $terms ) ) {
138 - $terms = _learn_press_usort_terms_by_ID( $terms ); // order by ID
139 - $category_object = apply_filters(
140 - 'learn_press_course_post_type_link_course_category',
141 - $terms[0],
142 - $terms,
143 - $post
144 - );
145 - $category_object = get_term( $category_object, 'course_category' );
146 - $course_category = $category_object->slug;
147 -
148 - $parent = $category_object->parent;
149 - if ( $parent ) {
150 - $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
151 - foreach ( $ancestors as $ancestor ) {
152 - $ancestor_object = get_term( $ancestor, 'course_category' );
153 - $course_category = $ancestor_object->slug . '/' . $course_category;
154 - }
155 - }
156 - } else {
157 - // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
158 - $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
159 - }
160 -
161 - $find = array(
162 - '%year%',
163 - '%monthnum%',
164 - '%day%',
165 - '%hour%',
166 - '%minute%',
167 - '%second%',
168 - '%post_id%',
169 - '%category%',
170 - '%course_category%',
171 - );
172 -
173 - $replace = array(
174 - date_i18n( 'Y', strtotime( $post->post_date ) ),
175 - date_i18n( 'm', strtotime( $post->post_date ) ),
176 - date_i18n( 'd', strtotime( $post->post_date ) ),
177 - date_i18n( 'H', strtotime( $post->post_date ) ),
178 - date_i18n( 'i', strtotime( $post->post_date ) ),
179 - date_i18n( 's', strtotime( $post->post_date ) ),
180 - $post->ID,
181 - $course_category,
182 - $course_category,
183 - );
184 -
185 - $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 );
186 202 }
187 203
188 204 return $post_link;
189 205 }
190 206
191 - private function has_block_template( $template_name ) {
192 - if ( ! $template_name ) {
193 - return false;
194 - }
195 -
196 - $has_template = false;
197 - $template_name = str_replace( 'course', LP_COURSE_CPT, $template_name );
198 - $template_filename = $template_name . '.html';
199 - // Since Gutenberg 12.1.0, the conventions for block templates directories have changed,
200 - // we should check both these possible directories for backwards-compatibility.
201 - $possible_templates_dirs = array( 'templates', 'block-templates' );
202 -
203 - // Combine the possible root directory names with either the template directory
204 - // or the stylesheet directory for child themes, getting all possible block templates
205 - // locations combinations.
206 - $filepath = DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template_filename;
207 - $legacy_filepath = DIRECTORY_SEPARATOR . 'block-templates' . DIRECTORY_SEPARATOR . $template_filename;
208 - $possible_paths = array(
209 - get_stylesheet_directory() . $filepath,
210 - get_stylesheet_directory() . $legacy_filepath,
211 - get_template_directory() . $filepath,
212 - get_template_directory() . $legacy_filepath,
213 - );
214 -
215 - // Check the first matching one.
216 - foreach ( $possible_paths as $path ) {
217 - if ( is_readable( $path ) ) {
218 - $has_template = true;
219 - break;
220 - }
221 - }
222 -
223 - /**
224 - * Filters the value of the result of the block template check.
225 - *
226 - * @since x.x.x
227 - *
228 - * @param boolean $has_template value to be filtered.
229 - * @param string $template_name The name of the template.
230 - */
231 - return (bool) apply_filters( 'learnpress_has_block_template', $has_template, $template_name );
232 - }
233 -
234 207 /**
235 208 * Set title of pages
236 209 *
237 210 * 1. Title course archive page
@@ -240,23 +213,21 @@
240 213 *
241 214 * @param string $title
242 215 *
243 216 * @return string
217 + * @throws Exception
218 + * @since 3.2.7.7
219 + * @version 1.0.2
244 220 * @author tungnx
245 - * @since 3.2.7.7
246 221 */
247 - public function set_title_pages( string $title = '' ): string {
248 - global $wp_query;
222 + public function set_title_pages( $title = '' ): string {
249 223 $flag_title_course = false;
224 + $user_id = get_current_user_id();
250 225
251 - $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 );
252 227
253 - // Set title course archive page
254 - if ( ! empty( $course_archive_page_id ) && $wp_query->post &&
255 - $course_archive_page_id == $wp_query->post->ID ) {
256 - $title = get_the_title( $course_archive_page_id );
257 - $flag_title_course = true;
258 - } elseif ( learn_press_is_course() ) {
228 + // Set title single course.
229 + if ( learn_press_is_course() ) {
259 230 $item = LP_Global::course_item();
260 231 if ( $item ) {
261 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
262 233
@@ -261,21 +232,33 @@
261 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
262 233
263 234 $flag_title_course = true;
264 235 }
265 - } elseif ( learn_press_is_courses() ) {
266 - if ( learn_press_is_search() ) {
236 + } elseif ( LP_Page_Controller::is_page_courses() ) { // Set title course archive page.
237 + if ( isset( $_GET['c_search'] ) ) {
267 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 + }
268 247 } else {
269 - $title = __( 'Courses', 'learnpress' );
248 + $title = $course_archive_page_id ? get_the_title( $course_archive_page_id ) : __( 'Courses', 'learnpress' );
270 249 }
271 250
272 251 $flag_title_course = true;
273 - } elseif ( learn_press_is_profile() ) {
274 - $profile = LP_Profile::instance();
275 - $tab_slug = $profile->get_current_tab();
276 - $tab = $profile->get_tab_at( $tab_slug );
277 - $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 + }
278 261
279 262 if ( $page_id ) {
280 263 $page_title = get_the_title( $page_id );
281 264 } else {
@@ -280,9 +263,10 @@
280 263 $page_title = get_the_title( $page_id );
281 264 } else {
282 265 $page_title = '';
283 266 }
284 - if ( $tab ) {
267 +
268 + if ( $tab instanceof LP_Profile_Tab ) {
285 269 $title = join(
286 270 ' ',
287 271 apply_filters(
288 272 'learn-press/document-profile-title-parts',
@@ -288,12 +272,14 @@
288 272 'learn-press/document-profile-title-parts',
289 273 array(
290 274 $page_title,
291 275 '&rarr;',
292 - $tab['title'],
276 + $tab->get( 'title' ),
293 277 )
294 278 )
295 279 );
280 + } else {
281 + $title = $page_title;
296 282 }
297 283
298 284 $flag_title_course = true;
299 285 }
@@ -301,8 +287,12 @@
301 287 if ( $flag_title_course ) {
302 288 $title .= ' - ' . get_bloginfo( 'name', 'display' );
303 289 }
304 290
291 + if ( ! is_string( $title ) ) {
292 + $title = get_bloginfo( 'name', 'display' );
293 + }
294 +
305 295 return apply_filters( 'learn-press/title-page', $title );
306 296 }
307 297
308 298 /**
@@ -328,56 +318,19 @@
328 318
329 319 return $desc;
330 320 }
331 321
332 - public function check_pages( $template ) {
333 - if ( learn_press_is_checkout() ) {
334 - $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
335 -
336 - if ( ! $available_gateways ) {
337 - learn_press_add_message( __( 'No payment method is available.', 'learnpress' ), 'error' );
338 - }
339 - } else {
340 - global $wp_query;
341 -
342 - $logout_slug = learn_press_profile_logout_slug();
343 -
344 - if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
345 - wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
346 - exit;
347 - }
348 - }
349 -
350 - return $template;
351 - }
352 -
353 322 /**
354 - * Auto inserting a registered shortcode to a specific page
355 - * if that page is viewing in single mode.
356 - *
357 - * @param string $template
358 - *
359 - * @return string;
360 - * @since 3.3.0
323 + * Handle logout
361 324 */
362 - public function auto_shortcode( $template ) {
363 - global $post;
364 - $the_post = $post;
365 - if ( $the_post && is_page( $the_post->ID ) ) {
325 + public function logout( $template ) {
326 + global $wp_query;
366 327
367 - // Filter here to insert the shortcode
368 - $auto_shortcodes = apply_filters( 'learn-press/auto-shortcode-pages', array() );
328 + $logout_slug = learn_press_profile_logout_slug();
369 329
370 - if ( ! empty( $auto_shortcodes[ $the_post->ID ] ) ) {
371 - $shortcode_tag = $auto_shortcodes[ $the_post->ID ];
372 -
373 - preg_match( '/\[' . $shortcode_tag . '\s?(.*)\]/', $the_post->post_content, $results );
374 -
375 - if ( empty( $results ) ) {
376 - $content = $the_post->post_content . "[$shortcode_tag]";
377 - $the_post->post_content = $content;
378 - }
379 - }
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;
380 333 }
381 334
382 335 return $template;
383 336 }
@@ -398,8 +351,12 @@
398 351 * @var LP_Course $lp_course
399 352 * @var LP_Course_Item|LP_Quiz|LP_Lesson $lp_course_item
400 353 */
401 354 global $wp, $wp_query, $lp_course_item;
355 + $vars = $wp->query_vars;
356 + if ( empty( $vars['course-item'] ) ) {
357 + return $post;
358 + }
402 359
403 360 if ( LP_COURSE_CPT !== $post->post_type ) {
404 361 return $post;
405 362 }
@@ -409,24 +366,30 @@
409 366 return $post;
410 367 }
411 368
412 369 /**
413 - * @deprecated v4.1.6.1 LP()->global['course'], $GLOBALS['course']
414 - * Some theme still use: global $course; LP()->global['course']
370 + * Use for case not load course via send params, use global instead.
371 + * Not recommended for use
372 + * This method is only purpose instead get_the_ID(), on file item of course.
373 + * When all file write by standard callback send param courseModel, this method will be removed.
374 + *
375 + * @return false|CourseModel
376 + * @since 4.2.7.4
415 377 */
416 - //LP()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
417 - LP()->global['course'] = $GLOBALS['course'] = $course;
378 + global $lpCourseModel;
379 + $lpCourseModel = CourseModel::find( $course->get_id(), true );
418 380
419 - if ( wp_verify_nonce( LP_Request::get( 'preview' ), 'preview-' . $post->ID ) ) {
381 + /**
382 + * @deprecated v4.1.6.1 LearnPress::instance()->global['course'], $GLOBALS['course']
383 + * Some theme still use: global $course; LearnPress::instance()->global['course']
384 + */
385 + //LearnPress::instance()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
386 + LearnPress::instance()->global['course'] = $GLOBALS['course'] = $course;
387 +
388 + if ( wp_verify_nonce( LP_Request::get_param( 'preview' ), 'preview-' . $post->ID ) ) {
420 389 $GLOBALS['preview_course'] = $post->ID;
421 390 }
422 391
423 - $vars = $wp->query_vars;
424 -
425 - if ( empty( $vars['course-item'] ) ) {
426 - return $post;
427 - }
428 -
429 392 if ( ! $wp_query->is_main_query() ) {
430 393 return $post;
431 394 }
432 395
@@ -433,14 +396,10 @@
433 396 try {
434 397 $user = learn_press_get_current_user();
435 398
436 399 // If item name is set in query vars
437 - if ( ! is_numeric( $vars['course-item'] ) ) {
438 - $item_type = $vars['item-type'];
439 - $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
440 - } else {
441 - $post_item = get_post( absint( $vars['course-item'] ) );
442 - }
400 + $item_type = $vars['item-type'];
401 + $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
443 402
444 403 if ( ! $post_item ) {
445 404 return $post;
446 405 }
@@ -452,29 +411,15 @@
452 411 }
453 412
454 413 // Set item viewing
455 414 $user->set_viewing_item( $lp_course_item );
456 - } catch ( Exception $ex ) {
457 - learn_press_add_message( $ex->getMessage(), 'error' );
415 + } catch ( Throwable $e ) {
416 + error_log( $e->getMessage() );
458 417 }
459 418
460 419 return $post;
461 420 }
462 421
463 - /**
464 - * Set page 404
465 - *
466 - * @return mixed
467 - * @editor tungnx
468 - * @reason not use
469 - * @deprecated 4.0.0
470 - */
471 - /*
472 - public function set_404( $is_404 ) {
473 - global $wp_query;
474 - $wp_query->is_404 = $this->_is_404 = (bool) $is_404;
475 - }*/
476 -
477 422 public function is_404() {
478 423 return apply_filters( 'learn-press/query/404', $this->_is_404 );
479 424 }
480 425
@@ -498,17 +443,23 @@
498 443 }
499 444
500 445 /**
501 446 * @return bool
447 + * @deprecated v4.2.7.6
502 448 */
503 449 protected function _is_archive() {
450 + _deprecated_function( __METHOD__, '4.1.7.3' );
451 + return false;
504 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();
505 453 }
506 454
507 455 /**
508 456 * @return bool
457 + * @deprecated v4.2.7.6
509 458 */
510 459 protected function _is_single() {
460 + _deprecated_function( __METHOD__, '4.1.7.3' );
461 + return false;
511 462 return learn_press_is_course() && is_single();
512 463 }
513 464
514 465 /**
@@ -518,8 +469,11 @@
518 469 *
519 470 * @return bool|string
520 471 */
521 472 public function template_loader( $template ) {
473 + if ( wp_is_block_theme() ) {
474 + return $template;
475 + }
522 476
523 477 if ( is_embed() ) {
524 478 return $template;
525 479 }
@@ -548,8 +502,18 @@
548 502 return $template;
549 503 }
550 504
551 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 + /**
552 516 * Get the default filename for a template.
553 517 *
554 518 * @return string
555 519 * @since 4.0.0
@@ -555,40 +519,59 @@
555 519 * @since 4.0.0
556 520 */
557 521 private function get_page_template() {
558 522 $page_template = '';
523 + $object = get_queried_object();
559 524
560 - if ( is_singular( LP_COURSE_CPT ) ) {
561 - 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
562 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';
563 544 }
564 545
565 - if ( $this->_is_single() ) {
566 - global $post;
567 - setup_postdata( $post );
546 + // Old single course layout.
547 + //$page_template = 'single-course.php';
568 548
569 - $course_item = LP_Global::course_item();
570 - if ( $course_item && ! self::has_block_template( 'content-single-course-item' ) ) {
571 - $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';
572 559 }
573 560 }
574 561 } elseif ( learn_press_is_course_taxonomy() ) {
575 - $object = get_queried_object();
576 -
577 562 if ( is_tax( 'course_category' ) || is_tax( 'course_tag' ) ) {
578 563 $page_template = 'taxonomy-' . $object->taxonomy . '.php';
579 564
580 - if ( self::has_block_template( 'taxonomy-' . $object->taxonomy ) ) {
581 - $page_template = '';
582 - } 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 ) ) ) {
583 566 $page_template = 'archive-course.php';
584 567 }
585 - } elseif ( ! self::has_block_template( 'archive-course' ) ) {
568 + } else {
586 569 $page_template = 'archive-course.php';
587 570 }
588 - } 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() ) {
589 572 $page_template = 'archive-course.php';
590 - } elseif ( learn_press_is_checkout() && ! self::has_block_template( 'page-lp_checkout' ) ) {
573 + } elseif ( learn_press_is_checkout() ) {
591 574 $page_template = 'pages/checkout.php';
592 575 }
593 576
594 577 return apply_filters( 'learn-press/page-template', $page_template );
@@ -609,9 +592,9 @@
609 592 }
610 593 }
611 594 }
612 595
613 - if ( is_singular( LP_COURSE_CPT ) ) {
596 + /*if ( is_singular( LP_COURSE_CPT ) ) {
614 597 $object = get_queried_object();
615 598 $name_decoded = urldecode( $object->post_name );
616 599
617 600 if ( $name_decoded !== $object->post_name ) {
@@ -618,53 +601,25 @@
618 601 $templates[] = "single-course-$name_decoded.php";
619 602 }
620 603
621 604 $templates[] = "single-product-$object->post_name.php";
622 - }
605 + }*/
623 606
624 607 if ( learn_press_is_course_taxonomy() ) {
625 608 $object = get_queried_object();
626 609 $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
627 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
610 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
628 611 $templates[] = 'taxonomy-' . $object->taxonomy . '.php';
629 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '.php';
612 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '.php';
630 613 }
631 614
632 615 $templates[] = $default_template;
633 - $templates[] = learn_press_template_path( true ) . $default_template;
616 + $templates[] = learn_press_template_path() . '/' . $default_template;
634 617
635 618 return array_unique( $templates );
636 619 }
637 620
638 621 /**
639 - * Filter to allow search more templates in theme for wp page template hierarchy.
640 - * Theme twentytwenty used 'singular.php' instead of 'page.php'
641 - *
642 - * @param array $templates
643 - *
644 - * @return array
645 - * @since 3.x.x
646 - * @depecated 4.1.6.9.2
647 - */
648 - /*public function page_template_hierarchy( $templates ) {
649 - $templates = array_merge( $templates, array( 'singular.php' ) );
650 -
651 - return $templates;
652 - }*/
653 -
654 - /**
655 - * Archive course content.
656 - *
657 - * @return false|string
658 - */
659 - public function archive_content() {
660 - ob_start();
661 - learn_press_get_template( 'content-archive-course.php' );
662 -
663 - return ob_get_clean();
664 - }
665 -
666 - /**
667 622 * @param $title
668 623 *
669 624 * @return mixed
670 625 */
@@ -683,11 +638,11 @@
683 638 * @param $q WP_Query
684 639 *
685 640 * @return WP_Query
686 641 * @editor tungnx
642 + * @throws Exception
643 + * @version 4.1.3
687 644 * @since 3.0.0
688 - * @version 4.1.3
689 - * @throws Exception
690 645 */
691 646 public function pre_get_posts( WP_Query $q ): WP_Query {
692 647 // Affect only the main query and not in admin
693 648 if ( ! $q->is_main_query() && ! is_admin() ) {
@@ -694,11 +649,11 @@
694 649 return $q;
695 650 }
696 651
697 652 try {
698 - if ( LP_Page_Controller::page_current() === LP_PAGE_COURSES ) {
699 - if ( ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses() ) ) {
700 - LP()->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() ) {
701 656 /**
702 657 * If page is archive course - query set posts_per_page = 1
703 658 * For fastest - because when page loaded - call API to load list courses
704 659 *
@@ -704,22 +659,28 @@
704 659 *
705 660 * Current, apply only for LP, not apply for theme Thimpress, because theme override
706 661 */
707 662 $q->set( 'posts_per_page', 1 );
708 - $q->set( 'posts_per_archive_page', 1 );
709 - $q->set( 'nopaging', true );
663 + $q->set( 'suppress_filters', true );
664 + //$q->set( 'posts_per_archive_page', 1 );
665 + //$q->set( 'nopaging', true );
710 666 } else {
711 667 $filter = new LP_Course_Filter();
712 668 $filter->only_fields = [ 'ID' ];
713 - $filter->limit = -1;
669 + $filter->limit = - 1;
714 670 $is_need_check_in_arr = false;
715 671 $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
716 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 +
717 679 $q->set( 'posts_per_page', $limit );
718 680 // $q->set( 'cache_results', true ); // it default true
719 681
720 682 // Search courses by keyword
721 - // $q->set( 's', $_REQUEST['c_search'] ?? '' );
722 683 if ( ! empty( $_REQUEST['c_search'] ) ) {
723 684 $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
724 685 $is_need_check_in_arr = true;
725 686 }
@@ -728,9 +689,9 @@
728 689 if ( ! empty( $author_ids_str ) ) {
729 690 $q->set( 'author', $author_ids_str );
730 691 }
731 692
732 - // Meta query
693 + // Search course has price/free
733 694 $meta_query = [];
734 695 if ( isset( $_REQUEST['sort_by'] ) ) {
735 696 $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
736 697 if ( 'on_paid' === $sort_by ) {
@@ -742,25 +703,67 @@
742 703 }
743 704
744 705 if ( 'on_free' === $sort_by ) {
745 706 $meta_query[] = array(
746 - 'key' => '_lp_price',
747 - 'value' => 0,
748 - '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 + ],
749 722 );
750 723 }
751 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 +
752 738 $q->set( 'meta_query', $meta_query );
753 739 // End Meta query
754 740
755 - // Tax query
741 + // Search on Category
742 + $args_cat = lp_archive_skeleton_get_args();
756 743 $tax_query = [];
757 - $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 + );
758 747 if ( ! empty( $term_ids_str ) ) {
759 748 $term_ids = explode( ',', $term_ids_str );
760 749
761 750 $tax_query[] = array(
762 - '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',
763 766 'field' => 'term_id',
764 767 'terms' => $term_ids,
765 768 'operator' => 'IN',
766 769 );
@@ -800,9 +803,9 @@
800 803 $q->set( 'order', $order );
801 804 }
802 805
803 806 if ( $is_need_check_in_arr ) {
804 - $posts_in = LP_Course::get_courses( $filter );
807 + $posts_in = Courses::get_courses( $filter );
805 808 if ( ! empty( $posts_in ) ) {
806 809 $posts_in = LP_Database::get_values_by_key( $posts_in );
807 810 $q->set( 'post__in', $posts_in );
808 811 } else {
@@ -817,35 +820,21 @@
817 820 }
818 821
819 822 // Exclude item not assign
820 823 if ( $q->is_search() ) {
821 - // Exclude item not assign any course
822 - $course_item_types = learn_press_get_course_item_types();
823 - $list_ids_exclude = array();
824 -
825 - foreach ( $course_item_types as $item_type ) {
826 - $filter = new LP_Post_Type_Filter();
827 - $filter->post_type = $item_type;
828 - $exclude_item = LP_Course_DB::getInstance()->get_item_ids_unassigned( $filter );
829 - $exclude_item = LP_Course_DB::get_values_by_key( $exclude_item );
830 -
831 - $list_ids_exclude = array_merge( $list_ids_exclude, $exclude_item );
832 - }
833 -
834 - // Exclude question not assign any quiz
835 - $question_ids = LP_Question_DB::getInstance()->get_questions_not_assign_quiz();
836 - $question_ids = LP_Course_DB::get_values_by_key( $question_ids );
837 - $list_ids_exclude = array_merge( $list_ids_exclude, $question_ids );
838 -
839 - if ( ! empty( $list_ids_exclude ) ) {
840 - $q->set( 'post__not_in', $list_ids_exclude );
841 - }
842 -
843 824 return $q;
844 825 }
845 826
846 827 // Handle 404 if user are viewing course item directly.
847 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 + }
848 837 } catch ( Throwable $e ) {
849 838 error_log( $e->getMessage() );
850 839 }
851 840
@@ -857,16 +846,25 @@
857 846 * Example: http://example.com/lesson/slug-lesson
858 847 * Apply for user not admin, instructor, co-instructor
859 848 *
860 849 * @param WP_Query $q
850 + *
861 851 * @editor tungnx
862 852 * @since 3.2.7.5
863 853 */
864 854 public function set_link_item_course_default_wp_to_page_404( $q ) {
865 - $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 + );
866 864
867 865 if ( ! isset( $q->query_vars['post_type'] ) || ! in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
868 - return $q;
866 + return;
869 867 }
870 868
871 869 try {
872 870 $flag_load_404 = true;
@@ -895,9 +893,9 @@
895 893
896 894 $flag_load_404 = apply_filters( 'learnpress/page/set-link-item-course-404', $flag_load_404, $post_author, $user );
897 895
898 896 if ( $flag_load_404 ) {
899 - learn_press_404_page();
897 + self::set_page_404();
900 898 }
901 899 } catch ( Throwable $e ) {
902 900 error_log( $e->getMessage() );
903 901 }
@@ -903,43 +901,8 @@
903 901 }
904 902 }
905 903
906 904 /**
907 - * @depecated 4.1.6.9.2
908 - */
909 - /*public function the_content_callback( $content ) {
910 - if ( $this->_archive_contents ) {
911 - preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
912 - $this->_shortcode_exists = ! empty( $results );
913 - if ( $this->_shortcode_exists ) {
914 - $this->_shortcode_tag = $results[0];
915 - $content = str_replace( $this->_shortcode_tag, $this->_archive_contents, $content );
916 - } else {
917 - $content .= $this->_archive_contents;
918 - }
919 - }
920 -
921 - return $content;
922 - }*/
923 -
924 - /**
925 - * Check is page Become a teacher
926 - *
927 - * @return bool|mixed|void
928 - * @since 3.2.8
929 - * @author tungnx
930 - */
931 - public static function is_page_become_a_teacher() {
932 - $page_id = learn_press_get_page_id( 'become_a_teacher' );
933 -
934 - if ( $page_id && is_page( $page_id ) ) {
935 - return true;
936 - }
937 -
938 - return apply_filters( 'learnpress/is-page/become-a-teacher', false );
939 - }
940 -
941 - /**
942 905 * Get page current on frontend
943 906 *
944 907 * @return string
945 908 * @since 3.2.8
@@ -950,36 +913,275 @@
950 913 * @var WP_Query $wp_query
951 914 */
952 915 global $wp_query;
953 916
917 + // Course Builder page detection
918 + if ( self::is_page_course_builder() ) {
919 + return LP_PAGE_COURSE_BUILDER;
920 + }
921 +
954 922 if ( ! is_object( $wp_query ) || ! $wp_query->get_queried_object() ) {
955 923 return '';
956 924 }
957 925
958 - if ( learn_press_is_checkout() ) {
926 + if ( self::is_page_checkout() ) {
959 927 return LP_PAGE_CHECKOUT;
960 928 } elseif ( LP_Global::course_item_quiz() ) {
961 929 return LP_PAGE_QUIZ;
962 930 } elseif ( learn_press_is_course() && LP_Global::course_item() ) {
963 931 return LP_PAGE_SINGLE_COURSE_CURRICULUM;
964 - } elseif ( learn_press_is_courses() ) {
932 + } elseif ( self::is_page_courses() ) {
965 933 return LP_PAGE_COURSES;
966 934 } elseif ( learn_press_is_course() ) {
967 935 return LP_PAGE_SINGLE_COURSE;
968 936 } elseif ( self::is_page_become_a_teacher() ) {
969 937 return LP_PAGE_BECOME_A_TEACHER;
970 - } elseif ( learn_press_is_profile() ) {
938 + } elseif ( self::is_page_profile() ) {
971 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;
972 944 } else {
973 945 return apply_filters( 'learnpress/page/current', '' );
974 946 }
975 947 }
976 948
977 - public static function instance() {
978 - if ( is_admin() ) {
979 - 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;
980 960 }
981 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() {
982 1184 if ( ! self::$_instance ) {
983 1185 self::$_instance = new self();
984 1186 }
985 1187
@@ -991,10 +1193,14 @@
991 1193 *
992 1194 * @editor tungnx
993 1195 * @version 1.0.1
994 1196 * @since 3.0.0
1197 + * @deprecated 4.1.7.3
995 1198 */
996 1199 public function learn_press_edit_admin_bar() {
1200 + _deprecated_function( __METHOD__, '4.1.7.3' );
1201 + return;
1202 +
997 1203 global $wp_admin_bar;
998 1204
999 1205 $current_user = wp_get_current_user();
1000 1206
@@ -1002,11 +1208,11 @@
1002 1208 return;
1003 1209 }
1004 1210
1005 1211 $page_profile_id = learn_press_get_page_id( 'profile' );
1006 -
1007 1212 if ( $page_profile_id && get_post_status( $page_profile_id ) != 'trash' ) {
1008 1213 $user_id = $current_user->ID;
1214 + $profile = LP_Profile::instance( $user_id );
1009 1215
1010 1216 $wp_admin_bar->add_menu(
1011 1217 array(
1012 1218 'id' => 'course_profile',
@@ -1011,9 +1217,9 @@
1011 1217 array(
1012 1218 'id' => 'course_profile',
1013 1219 'parent' => 'user-actions',
1014 1220 'title' => get_the_title( $page_profile_id ),
1015 - 'href' => learn_press_user_profile_link( $user_id, false ),
1221 + 'href' => $profile->get_tab_link(),
1016 1222 )
1017 1223 );
1018 1224 }
1019 1225 }
@@ -1034,7 +1240,86 @@
1034 1240 }
1035 1241
1036 1242 return $send_no_cache_headers;
1037 1243 }
1244 +
1245 + /**
1246 + * Override lesson comment permalink.
1247 + *
1248 + * @param string $link The comment permalink with '#comment-$id' appended.
1249 + * @param WP_Comment $comment The current comment object.
1250 + *
1251 + * @return string $link The comment permalink with '#comment-$id' appended.
1252 + * @since 4.2.3
1253 + * @version 1.0.0
1254 + */
1255 + public function edit_lesson_comment_links( $link, $comment ): string {
1256 + try {
1257 + $comment = get_comment( $comment );
1258 + if ( get_post_type( $comment->comment_post_ID ) == LP_LESSON_CPT ) {
1259 + $link = wp_get_referer() . '#comment-' . $comment->comment_ID;
1260 + }
1261 +
1262 + return $link;
1263 + } catch ( Throwable $e ) {
1264 + error_log( $e->getMessage() );
1265 + }
1266 +
1267 + return $link;
1268 + }
1269 +
1270 + /**
1271 + * Set menu active for page courses.
1272 + *
1273 + * @param $menu_items
1274 + *
1275 + * @return mixed
1276 + */
1277 + public function menu_active( $menu_items ) {
1278 + $course_page = learn_press_get_page_id( 'courses' );
1279 + $page_for_posts = (int) get_option( 'page_for_posts' );
1280 +
1281 + if ( is_array( $menu_items ) && ! empty( $menu_items ) ) {
1282 + foreach ( $menu_items as $key => $menu_item ) {
1283 + $classes = (array) $menu_item->classes;
1284 + $menu_id = (int) $menu_item->object_id;
1285 +
1286 + // Unset active class for blog page.
1287 + if ( $page_for_posts === $menu_id ) {
1288 + $menu_item->current = false;
1289 +
1290 + if ( in_array( 'current_page_parent', $classes, true ) ) {
1291 + unset( $classes[ array_search( 'current_page_parent', $classes, true ) ] );
1292 + }
1293 +
1294 + if ( in_array( 'current-menu-item', $classes, true ) ) {
1295 + unset( $classes[ array_search( 'current-menu-item', $classes, true ) ] );
1296 + }
1297 + } elseif ( ( is_post_type_archive( 'lp_course' ) || is_page( $course_page ) ) && $course_page === $menu_id && 'page' === $menu_item->object ) {
1298 + // Set active state if this is the shop page link.
1299 + $menu_item->current = true;
1300 + $classes[] = 'current-menu-item';
1301 + $classes[] = 'current_page_item';
1302 + } elseif ( is_singular( 'lp_course' ) && $course_page === $menu_id ) {
1303 + // Set parent state if this is a product page.
1304 + $classes[] = 'current_page_parent';
1305 + }
1306 +
1307 + $menu_item->classes = array_unique( $classes );
1308 + $menu_items[ $key ] = $menu_item;
1309 + }
1310 + }
1311 +
1312 + return $menu_items;
1313 + }
1314 +
1315 + /**
1316 + * Set Page viewing to 404
1317 + *
1318 + * @return void
1319 + */
1320 + public static function set_page_404() {
1321 + global $wp_query;
1322 + $wp_query->set_404();
1323 + status_header( 404 );
1324 + }
1038 1325 }
1039 -
1040 -return LP_Page_Controller::instance();