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 +773 -535 4.1.74.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 {
@@ -10,14 +16,14 @@
10 16 * Store the object has queried by WP.
11 17 *
12 18 * @var int
13 19 */
14 - protected $_queried_object = 0;
20 + //protected $_queried_object = 0;
15 21
16 22 /**
17 23 * @var int
18 24 */
19 - protected $_filter_content_priority = 10000;
25 + //protected $_filter_content_priority = 10000;
20 26
21 27 /**
22 28 * Flag for 404 content.
23 29 *
@@ -28,102 +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' ), 10 );
33 - add_filter( 'template_include', array( $this, 'template_loader' ), 10 );
34 - add_filter( 'template_include', array( $this, 'check_pages' ), 30 );
35 - add_filter( 'template_include', array( $this, 'auto_shortcode' ), 50 );
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' ) );
52 - add_action( 'plugins_loaded', array( $this, 'lp_rest_api_called' ), 1 );
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' ) );
58 - }
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 );
59 89
60 - /**
61 - * Optimize when Rest API LP called
62 - *
63 - * @return void
64 - */
65 - public function lp_rest_api_called() {
66 - if ( LP_Helper::isRestApiLP() ) {
67 - if ( ! defined( 'SHORTINIT' ) ) {
68 - define( 'SHORTINIT', true );
69 - }
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 );
70 93
71 - // Remove hook wp_loaded because query default WP run on it (it hooks 'pre_get_posts',...)
72 - remove_all_actions( 'after_setup_theme' );
73 - remove_all_actions( 'setup_theme' );
74 - remove_all_actions( 'muplugins_loaded' );
75 - remove_all_actions( 'network_plugin_loaded' );
76 - remove_all_actions( 'mu_plugin_loaded' );
77 - remove_all_actions( 'plugin_loaded' );
78 - remove_all_actions( 'wp_loaded' );
79 - //remove_all_actions( 'plugins_loaded' );
80 - remove_all_actions( 'pre_get_posts' );
81 - remove_all_actions( 'parse_query' );
82 - }
83 - }
94 + // Set link profile to admin menu
95 + //add_action( 'admin_bar_menu', array( $this, 'learn_press_edit_admin_bar' ) );
84 96
85 - /**
86 - * Check notify papal call when done.
87 - *
88 - * Set in param notify_url on @see LP_Gateway_Paypal::get_paypal_args()
89 - */
90 - public function check_webhook_paypal_ipn() {
91 - //error_log( 'xxx:' . json_encode( $_POST, JSON_UNESCAPED_UNICODE ) );
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' ) );
92 99
93 - // Paypal payment done
94 - if ( ! isset( $_GET['paypal_notify'] ) ) {
95 - return;
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 + );
96 115 }
97 116
98 - if ( ! isset( $_POST['ipn_track_id'] ) ) {
99 - return;
100 - }
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 + }
101 128
102 - try {
103 - $paypal = new LP_Gateway_Paypal();
104 - $verify = $paypal->validate_ipn();
129 + return $post_types;
130 + }
131 + );
105 132
106 - if ( $verify ) {
107 - if ( isset( $_POST['custom'] ) ) {
108 - $data_order = json_decode( LP_Helper::sanitize_params_submitted( $_POST['custom'] ) );
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 + }
109 146
110 - if ( json_last_error() === JSON_ERROR_NONE ) {
111 - $order_id = $data_order->order_id;
147 + return $is_viewable;
148 + },
149 + 10,
150 + 2
151 + );*/
152 + }
112 153
113 - $lp_order = learn_press_get_order( $order_id );
114 - $lp_order->set_status( 'completed' );
115 - $lp_order->save();
116 - }
117 - }
118 - }
119 - } catch ( Throwable $e ) {
120 - error_log( $e->getMessage() );
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' );
121 165 }
166 +
167 + return $link;
122 168 }
123 169
124 170 /**
125 - * Set link item course when form search default wp
171 + * Set link course, item course
126 172 *
127 173 * @param string $post_link
128 174 * @param object $post
129 175 */
@@ -128,20 +174,19 @@
128 174 * @param object $post
129 175 */
130 176 public function post_type_link( $post_link, $post ) {
131 177 // Set item's course permalink
132 - $course_item_types = learn_press_get_course_item_types();
178 + $course_item_types = CourseModel::item_types_support();
133 179 $item_id = $post->ID;
134 180
135 - 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() ) {
136 183 $section_id = LP_Section_DB::getInstance()->get_section_id_by_item_id( $item_id );
137 -
138 184 if ( ! $section_id ) {
139 185 return $post_link;
140 186 }
141 187
142 188 $course_id = LP_Section_DB::getInstance()->get_course_id_by_section( $section_id );
143 -
144 189 if ( ! $course_id ) {
145 190 return $post_link;
146 191 }
147 192
@@ -151,113 +196,15 @@
151 196 }
152 197
153 198 $post_link = $course->get_item_link( $item_id );
154 199 } elseif ( LP_COURSE_CPT === $post->post_type ) {
155 - // Abort early if the placeholder rewrite tag isn't in the generated URL
156 - if ( false === strpos( $post_link, '%' ) ) {
157 - return $post_link;
158 - }
159 -
160 - // Get the custom taxonomy terms in use by this post
161 - $terms = get_the_terms( $post->ID, 'course_category' );
162 -
163 - if ( ! empty( $terms ) ) {
164 - $terms = _learn_press_usort_terms_by_ID( $terms ); // order by ID
165 - $category_object = apply_filters(
166 - 'learn_press_course_post_type_link_course_category',
167 - $terms[0],
168 - $terms,
169 - $post
170 - );
171 - $category_object = get_term( $category_object, 'course_category' );
172 - $course_category = $category_object->slug;
173 -
174 - $parent = $category_object->parent;
175 - if ( $parent ) {
176 - $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
177 - foreach ( $ancestors as $ancestor ) {
178 - $ancestor_object = get_term( $ancestor, 'course_category' );
179 - $course_category = $ancestor_object->slug . '/' . $course_category;
180 - }
181 - }
182 - } else {
183 - // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
184 - $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
185 - }
186 -
187 - $find = array(
188 - '%year%',
189 - '%monthnum%',
190 - '%day%',
191 - '%hour%',
192 - '%minute%',
193 - '%second%',
194 - '%post_id%',
195 - '%category%',
196 - '%course_category%',
197 - );
198 -
199 - $replace = array(
200 - date_i18n( 'Y', strtotime( $post->post_date ) ),
201 - date_i18n( 'm', strtotime( $post->post_date ) ),
202 - date_i18n( 'd', strtotime( $post->post_date ) ),
203 - date_i18n( 'H', strtotime( $post->post_date ) ),
204 - date_i18n( 'i', strtotime( $post->post_date ) ),
205 - date_i18n( 's', strtotime( $post->post_date ) ),
206 - $post->ID,
207 - $course_category,
208 - $course_category,
209 - );
210 -
211 - $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 );
212 202 }
213 203
214 204 return $post_link;
215 205 }
216 206
217 - private function has_block_template( $template_name ) {
218 - if ( ! $template_name ) {
219 - return false;
220 - }
221 -
222 - $has_template = false;
223 - $template_name = str_replace( 'course', LP_COURSE_CPT, $template_name );
224 - $template_filename = $template_name . '.html';
225 - // Since Gutenberg 12.1.0, the conventions for block templates directories have changed,
226 - // we should check both these possible directories for backwards-compatibility.
227 - $possible_templates_dirs = array( 'templates', 'block-templates' );
228 -
229 - // Combine the possible root directory names with either the template directory
230 - // or the stylesheet directory for child themes, getting all possible block templates
231 - // locations combinations.
232 - $filepath = DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template_filename;
233 - $legacy_filepath = DIRECTORY_SEPARATOR . 'block-templates' . DIRECTORY_SEPARATOR . $template_filename;
234 - $possible_paths = array(
235 - get_stylesheet_directory() . $filepath,
236 - get_stylesheet_directory() . $legacy_filepath,
237 - get_template_directory() . $filepath,
238 - get_template_directory() . $legacy_filepath,
239 - );
240 -
241 - // Check the first matching one.
242 - foreach ( $possible_paths as $path ) {
243 - if ( is_readable( $path ) ) {
244 - $has_template = true;
245 - break;
246 - }
247 - }
248 -
249 - /**
250 - * Filters the value of the result of the block template check.
251 - *
252 - * @since x.x.x
253 - *
254 - * @param boolean $has_template value to be filtered.
255 - * @param string $template_name The name of the template.
256 - */
257 - return (bool) apply_filters( 'learnpress_has_block_template', $has_template, $template_name );
258 - }
259 -
260 207 /**
261 208 * Set title of pages
262 209 *
263 210 * 1. Title course archive page
@@ -266,23 +213,21 @@
266 213 *
267 214 * @param string $title
268 215 *
269 216 * @return string
217 + * @throws Exception
218 + * @since 3.2.7.7
219 + * @version 1.0.2
270 220 * @author tungnx
271 - * @since 3.2.7.7
272 221 */
273 - public function set_title_pages( string $title = '' ): string {
274 - global $wp_query;
222 + public function set_title_pages( $title = '' ): string {
275 223 $flag_title_course = false;
224 + $user_id = get_current_user_id();
276 225
277 - $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 );
278 227
279 - // Set title course archive page
280 - if ( ! empty( $course_archive_page_id ) && $wp_query->post &&
281 - $course_archive_page_id == $wp_query->post->ID ) {
282 - $title = get_the_title( $course_archive_page_id );
283 - $flag_title_course = true;
284 - } elseif ( learn_press_is_course() ) {
228 + // Set title single course.
229 + if ( learn_press_is_course() ) {
285 230 $item = LP_Global::course_item();
286 231 if ( $item ) {
287 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
288 233
@@ -287,21 +232,33 @@
287 232 $title = apply_filters( 'learn-press/document-course-title-parts', get_the_title() . ' &rarr; ' . $item->get_title(), $item );
288 233
289 234 $flag_title_course = true;
290 235 }
291 - } elseif ( learn_press_is_courses() ) {
292 - if ( learn_press_is_search() ) {
236 + } elseif ( LP_Page_Controller::is_page_courses() ) { // Set title course archive page.
237 + if ( isset( $_GET['c_search'] ) ) {
293 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 + }
294 247 } else {
295 - $title = __( 'Courses', 'learnpress' );
248 + $title = $course_archive_page_id ? get_the_title( $course_archive_page_id ) : __( 'Courses', 'learnpress' );
296 249 }
297 250
298 251 $flag_title_course = true;
299 - } elseif ( learn_press_is_profile() ) {
300 - $profile = LP_Profile::instance();
301 - $tab_slug = $profile->get_current_tab();
302 - $tab = $profile->get_tab_at( $tab_slug );
303 - $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 + }
304 261
305 262 if ( $page_id ) {
306 263 $page_title = get_the_title( $page_id );
307 264 } else {
@@ -306,9 +263,10 @@
306 263 $page_title = get_the_title( $page_id );
307 264 } else {
308 265 $page_title = '';
309 266 }
310 - if ( $tab ) {
267 +
268 + if ( $tab instanceof LP_Profile_Tab ) {
311 269 $title = join(
312 270 ' ',
313 271 apply_filters(
314 272 'learn-press/document-profile-title-parts',
@@ -314,12 +272,14 @@
314 272 'learn-press/document-profile-title-parts',
315 273 array(
316 274 $page_title,
317 275 '&rarr;',
318 - $tab['title'],
276 + $tab->get( 'title' ),
319 277 )
320 278 )
321 279 );
280 + } else {
281 + $title = $page_title;
322 282 }
323 283
324 284 $flag_title_course = true;
325 285 }
@@ -327,8 +287,12 @@
327 287 if ( $flag_title_course ) {
328 288 $title .= ' - ' . get_bloginfo( 'name', 'display' );
329 289 }
330 290
291 + if ( ! is_string( $title ) ) {
292 + $title = get_bloginfo( 'name', 'display' );
293 + }
294 +
331 295 return apply_filters( 'learn-press/title-page', $title );
332 296 }
333 297
334 298 /**
@@ -354,56 +318,19 @@
354 318
355 319 return $desc;
356 320 }
357 321
358 - public function check_pages( $template ) {
359 - if ( learn_press_is_checkout() ) {
360 - $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
361 -
362 - if ( ! $available_gateways ) {
363 - learn_press_add_message( __( 'No payment method is available.', 'learnpress' ), 'error' );
364 - }
365 - } else {
366 - global $wp_query;
367 -
368 - $logout_slug = learn_press_profile_logout_slug();
369 -
370 - if ( $logout_slug && ( $wp_query->get( 'view' ) === $logout_slug ) ) {
371 - wp_safe_redirect( str_replace( '&amp;', '&', wp_logout_url( learn_press_get_page_link( 'profile' ) ) ) );
372 - exit;
373 - }
374 - }
375 -
376 - return $template;
377 - }
378 -
379 322 /**
380 - * Auto inserting a registered shortcode to a specific page
381 - * if that page is viewing in single mode.
382 - *
383 - * @param string $template
384 - *
385 - * @return string;
386 - * @since 3.3.0
323 + * Handle logout
387 324 */
388 - public function auto_shortcode( $template ) {
389 - global $post;
390 - $the_post = $post;
391 - if ( $the_post && is_page( $the_post->ID ) ) {
325 + public function logout( $template ) {
326 + global $wp_query;
392 327
393 - // Filter here to insert the shortcode
394 - $auto_shortcodes = apply_filters( 'learn-press/auto-shortcode-pages', array() );
328 + $logout_slug = learn_press_profile_logout_slug();
395 329
396 - if ( ! empty( $auto_shortcodes[ $the_post->ID ] ) ) {
397 - $shortcode_tag = $auto_shortcodes[ $the_post->ID ];
398 -
399 - preg_match( '/\[' . $shortcode_tag . '\s?(.*)\]/', $the_post->post_content, $results );
400 -
401 - if ( empty( $results ) ) {
402 - $content = $the_post->post_content . "[$shortcode_tag]";
403 - $the_post->post_content = $content;
404 - }
405 - }
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;
406 333 }
407 334
408 335 return $template;
409 336 }
@@ -424,8 +351,12 @@
424 351 * @var LP_Course $lp_course
425 352 * @var LP_Course_Item|LP_Quiz|LP_Lesson $lp_course_item
426 353 */
427 354 global $wp, $wp_query, $lp_course_item;
355 + $vars = $wp->query_vars;
356 + if ( empty( $vars['course-item'] ) ) {
357 + return $post;
358 + }
428 359
429 360 if ( LP_COURSE_CPT !== $post->post_type ) {
430 361 return $post;
431 362 }
@@ -435,24 +366,30 @@
435 366 return $post;
436 367 }
437 368
438 369 /**
439 - * @deprecated v4.1.6.1 LP()->global['course'], $GLOBALS['course']
440 - * 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
441 377 */
442 - //LP()->global['course'] = $GLOBALS['course'] = $GLOBALS['lp_course'] = $course;
443 - LP()->global['course'] = $GLOBALS['course'] = $course;
378 + global $lpCourseModel;
379 + $lpCourseModel = CourseModel::find( $course->get_id(), true );
444 380
445 - 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 ) ) {
446 389 $GLOBALS['preview_course'] = $post->ID;
447 390 }
448 391
449 - $vars = $wp->query_vars;
450 -
451 - if ( empty( $vars['course-item'] ) ) {
452 - return $post;
453 - }
454 -
455 392 if ( ! $wp_query->is_main_query() ) {
456 393 return $post;
457 394 }
458 395
@@ -459,14 +396,10 @@
459 396 try {
460 397 $user = learn_press_get_current_user();
461 398
462 399 // If item name is set in query vars
463 - if ( ! is_numeric( $vars['course-item'] ) ) {
464 - $item_type = $vars['item-type'];
465 - $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
466 - } else {
467 - $post_item = get_post( absint( $vars['course-item'] ) );
468 - }
400 + $item_type = $vars['item-type'];
401 + $post_item = learn_press_get_post_by_name( $vars['course-item'], $item_type );
469 402
470 403 if ( ! $post_item ) {
471 404 return $post;
472 405 }
@@ -478,29 +411,15 @@
478 411 }
479 412
480 413 // Set item viewing
481 414 $user->set_viewing_item( $lp_course_item );
482 - } catch ( Exception $ex ) {
483 - learn_press_add_message( $ex->getMessage(), 'error' );
415 + } catch ( Throwable $e ) {
416 + error_log( $e->getMessage() );
484 417 }
485 418
486 419 return $post;
487 420 }
488 421
489 - /**
490 - * Set page 404
491 - *
492 - * @return mixed
493 - * @editor tungnx
494 - * @reason not use
495 - * @deprecated 4.0.0
496 - */
497 - /*
498 - public function set_404( $is_404 ) {
499 - global $wp_query;
500 - $wp_query->is_404 = $this->_is_404 = (bool) $is_404;
501 - }*/
502 -
503 422 public function is_404() {
504 423 return apply_filters( 'learn-press/query/404', $this->_is_404 );
505 424 }
506 425
@@ -524,17 +443,23 @@
524 443 }
525 444
526 445 /**
527 446 * @return bool
447 + * @deprecated v4.2.7.6
528 448 */
529 449 protected function _is_archive() {
450 + _deprecated_function( __METHOD__, '4.1.7.3' );
451 + return false;
530 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();
531 453 }
532 454
533 455 /**
534 456 * @return bool
457 + * @deprecated v4.2.7.6
535 458 */
536 459 protected function _is_single() {
460 + _deprecated_function( __METHOD__, '4.1.7.3' );
461 + return false;
537 462 return learn_press_is_course() && is_single();
538 463 }
539 464
540 465 /**
@@ -544,8 +469,11 @@
544 469 *
545 470 * @return bool|string
546 471 */
547 472 public function template_loader( $template ) {
473 + if ( wp_is_block_theme() ) {
474 + return $template;
475 + }
548 476
549 477 if ( is_embed() ) {
550 478 return $template;
551 479 }
@@ -574,8 +502,18 @@
574 502 return $template;
575 503 }
576 504
577 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 + /**
578 516 * Get the default filename for a template.
579 517 *
580 518 * @return string
581 519 * @since 4.0.0
@@ -581,40 +519,59 @@
581 519 * @since 4.0.0
582 520 */
583 521 private function get_page_template() {
584 522 $page_template = '';
523 + $object = get_queried_object();
585 524
586 - if ( is_singular( LP_COURSE_CPT ) ) {
587 - 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
588 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';
589 544 }
590 545
591 - if ( $this->_is_single() ) {
592 - global $post;
593 - setup_postdata( $post );
546 + // Old single course layout.
547 + //$page_template = 'single-course.php';
594 548
595 - $course_item = LP_Global::course_item();
596 - if ( $course_item && ! self::has_block_template( 'content-single-course-item' ) ) {
597 - $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';
598 559 }
599 560 }
600 561 } elseif ( learn_press_is_course_taxonomy() ) {
601 - $object = get_queried_object();
602 -
603 562 if ( is_tax( 'course_category' ) || is_tax( 'course_tag' ) ) {
604 563 $page_template = 'taxonomy-' . $object->taxonomy . '.php';
605 564
606 - if ( self::has_block_template( 'taxonomy-' . $object->taxonomy ) ) {
607 - $page_template = '';
608 - } 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 ) ) ) {
609 566 $page_template = 'archive-course.php';
610 567 }
611 - } elseif ( ! self::has_block_template( 'archive-course' ) ) {
568 + } else {
612 569 $page_template = 'archive-course.php';
613 570 }
614 - } 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() ) {
615 572 $page_template = 'archive-course.php';
616 - } elseif ( learn_press_is_checkout() && ! self::has_block_template( 'page-lp_checkout' ) ) {
573 + } elseif ( learn_press_is_checkout() ) {
617 574 $page_template = 'pages/checkout.php';
618 575 }
619 576
620 577 return apply_filters( 'learn-press/page-template', $page_template );
@@ -635,9 +592,9 @@
635 592 }
636 593 }
637 594 }
638 595
639 - if ( is_singular( LP_COURSE_CPT ) ) {
596 + /*if ( is_singular( LP_COURSE_CPT ) ) {
640 597 $object = get_queried_object();
641 598 $name_decoded = urldecode( $object->post_name );
642 599
643 600 if ( $name_decoded !== $object->post_name ) {
@@ -644,53 +601,25 @@
644 601 $templates[] = "single-course-$name_decoded.php";
645 602 }
646 603
647 604 $templates[] = "single-product-$object->post_name.php";
648 - }
605 + }*/
649 606
650 607 if ( learn_press_is_course_taxonomy() ) {
651 608 $object = get_queried_object();
652 609 $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
653 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
610 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
654 611 $templates[] = 'taxonomy-' . $object->taxonomy . '.php';
655 - $templates[] = learn_press_template_path( true ) . 'taxonomy-' . $object->taxonomy . '.php';
612 + $templates[] = learn_press_template_path() . '/taxonomy-' . $object->taxonomy . '.php';
656 613 }
657 614
658 615 $templates[] = $default_template;
659 - $templates[] = learn_press_template_path( true ) . $default_template;
616 + $templates[] = learn_press_template_path() . '/' . $default_template;
660 617
661 618 return array_unique( $templates );
662 619 }
663 620
664 621 /**
665 - * Filter to allow search more templates in theme for wp page template hierarchy.
666 - * Theme twentytwenty used 'singular.php' instead of 'page.php'
667 - *
668 - * @param array $templates
669 - *
670 - * @return array
671 - * @since 3.x.x
672 - * @depecated 4.1.6.9.2
673 - */
674 - /*public function page_template_hierarchy( $templates ) {
675 - $templates = array_merge( $templates, array( 'singular.php' ) );
676 -
677 - return $templates;
678 - }*/
679 -
680 - /**
681 - * Archive course content.
682 - *
683 - * @return false|string
684 - */
685 - public function archive_content() {
686 - ob_start();
687 - learn_press_get_template( 'content-archive-course.php' );
688 -
689 - return ob_get_clean();
690 - }
691 -
692 - /**
693 622 * @param $title
694 623 *
695 624 * @return mixed
696 625 */
@@ -709,10 +638,11 @@
709 638 * @param $q WP_Query
710 639 *
711 640 * @return WP_Query
712 641 * @editor tungnx
713 - * @modify 4.1.2
714 642 * @throws Exception
643 + * @version 4.1.3
644 + * @since 3.0.0
715 645 */
716 646 public function pre_get_posts( WP_Query $q ): WP_Query {
717 647 // Affect only the main query and not in admin
718 648 if ( ! $q->is_main_query() && ! is_admin() ) {
@@ -718,194 +648,195 @@
718 648 if ( ! $q->is_main_query() && ! is_admin() ) {
719 649 return $q;
720 650 }
721 651
722 - // Exclude item not assign
723 - if ( $q->is_search() ) {
724 - // Exclude item not assign any course
725 - $course_item_types = learn_press_get_course_item_types();
726 - $list_ids_exclude = array();
652 + try {
653 + if ( LP_Page_Controller::is_page_courses() ) {
654 + if ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses()
655 + && ! LP_Settings::theme_no_support_load_courses_ajax() ) {
656 + /**
657 + * If page is archive course - query set posts_per_page = 1
658 + * For fastest - because when page loaded - call API to load list courses
659 + *
660 + * Current, apply only for LP, not apply for theme Thimpress, because theme override
661 + */
662 + $q->set( 'posts_per_page', 1 );
663 + $q->set( 'suppress_filters', true );
664 + //$q->set( 'posts_per_archive_page', 1 );
665 + //$q->set( 'nopaging', true );
666 + } else {
667 + $filter = new LP_Course_Filter();
668 + $filter->only_fields = [ 'ID' ];
669 + $filter->limit = - 1;
670 + $is_need_check_in_arr = false;
671 + $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
727 672
728 - foreach ( $course_item_types as $item_type ) {
729 - $filter = new LP_Post_Type_Filter();
730 - $filter->post_type = $item_type;
731 - $exclude_item = LP_Course_DB::getInstance()->get_item_ids_unassigned( $filter );
732 - $exclude_item = LP_Course_DB::get_values_by_key( $exclude_item );
673 + if ( LP_Settings_Courses::is_ajax_load_courses() &&
674 + LP_Settings_Courses::get_type_pagination() != 'number' &&
675 + ! LP_Settings::theme_no_support_load_courses_ajax() ) {
676 + $q->set( 'paged', 1 );
677 + }
733 678
734 - $list_ids_exclude = array_merge( $list_ids_exclude, $exclude_item );
735 - }
679 + $q->set( 'posts_per_page', $limit );
680 + // $q->set( 'cache_results', true ); // it default true
736 681
737 - // Exclude question not assign any quiz
738 - $question_ids = LP_Question_DB::getInstance()->get_questions_not_assign_quiz();
739 - $question_ids = LP_Course_DB::get_values_by_key( $question_ids );
740 - $list_ids_exclude = array_merge( $list_ids_exclude, $question_ids );
682 + // Search courses by keyword
683 + if ( ! empty( $_REQUEST['c_search'] ) ) {
684 + $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
685 + $is_need_check_in_arr = true;
686 + }
741 687
742 - if ( ! empty( $list_ids_exclude ) ) {
743 - $q->set( 'post__not_in', $list_ids_exclude );
744 - }
745 - }
688 + $author_ids_str = LP_Helper::sanitize_params_submitted( $_REQUEST['c_authors'] ?? 0 );
689 + if ( ! empty( $author_ids_str ) ) {
690 + $q->set( 'author', $author_ids_str );
691 + }
746 692
747 - $is_archive_course = false;
693 + // Search course has price/free
694 + $meta_query = [];
695 + if ( isset( $_REQUEST['sort_by'] ) ) {
696 + $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
697 + if ( 'on_paid' === $sort_by ) {
698 + $meta_query[] = array(
699 + 'key' => '_lp_price',
700 + 'value' => 0,
701 + 'compare' => '>',
702 + );
703 + }
748 704
749 - // Handle 404 if user are viewing course item directly.
750 - $this->set_link_item_course_default_wp_to_page_404( $q );
705 + if ( 'on_free' === $sort_by ) {
706 + $meta_query[] = array(
707 + 'relation' => 'OR',
708 + [
709 + 'key' => '_lp_price',
710 + 'value' => 0,
711 + 'compare' => '=',
712 + ],
713 + [
714 + 'key' => '_lp_price',
715 + 'value' => '',
716 + 'compare' => '=',
717 + ],
718 + [
719 + 'key' => '_lp_price',
720 + 'compare' => 'NOT EXISTS',
721 + ],
722 + );
723 + }
724 + }
751 725
752 - $this->_queried_object = ! empty( $q->queried_object_id ) ? $q->queried_object : false;
726 + // Search by level
727 + $c_level = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['c_level'] ?? '' ) );
728 + if ( ! empty( $c_level ) ) {
729 + $c_level = str_replace( 'all', '', $c_level );
730 + $c_level = explode( ',', $c_level );
731 + $meta_query[] = array(
732 + 'key' => '_lp_level',
733 + 'value' => $c_level,
734 + 'compare' => 'IN',
735 + );
736 + }
753 737
754 - /**
755 - * If current page is used for courses page
756 - * Set on both: "Homepage" and "Posts page" on Reading Settings
757 - */
758 - $page_courses_id = learn_press_get_page_id( 'courses' );
738 + $q->set( 'meta_query', $meta_query );
739 + // End Meta query
759 740
760 - if ( $q->is_home() && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) == $page_courses_id ) {
761 - $is_archive_course = 1;
762 - // $q->is_home = false;
763 - // $q->set( 'page_id', get_option( 'page_on_front' ) );
764 - }
741 + // Search on Category
742 + $args_cat = lp_archive_skeleton_get_args();
743 + $tax_query = [];
744 + $term_ids_str = LP_Helper::sanitize_params_submitted(
745 + urldecode( $_REQUEST['term_id'] ?? $args_cat['page_term_id_current'] ?? '' )
746 + );
747 + if ( ! empty( $term_ids_str ) ) {
748 + $term_ids = explode( ',', $term_ids_str );
765 749
766 - /**
767 - * If current page is used for courses page and set as "Homepage"
768 - */
769 - if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $page_courses_id && $q->get( 'page_id' ) == $page_courses_id ) {
770 - $is_archive_course = 1;
750 + $tax_query[] = array(
751 + 'taxonomy' => 'course_category',
752 + 'field' => 'term_id',
753 + 'terms' => $term_ids,
754 + 'operator' => 'IN',
755 + 'include_children' => false,
756 + );
757 + }
771 758
772 - /*
773 - global $wp_post_types;
759 + // Tag query
760 + $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['tag_id'] ?? '' ) );
761 + if ( ! empty( $tag_ids_str ) ) {
762 + $term_ids = explode( ',', $tag_ids_str );
774 763
775 - $course_page = get_post( $page_courses_id );
776 - $this->_queried_object = $course_page;
777 - $wp_post_types[ LP_COURSE_CPT ]->ID = $course_page->ID;
778 - $wp_post_types[ LP_COURSE_CPT ]->post_title = $course_page->post_title;
779 - $wp_post_types[ LP_COURSE_CPT ]->post_name = $course_page->post_name;
780 - $wp_post_types[ LP_COURSE_CPT ]->post_type = $course_page->post_type;
781 - $wp_post_types[ LP_COURSE_CPT ]->ancestors = get_ancestors( $course_page->ID, $course_page->post_type );*/
782 - }
764 + $tax_query[] = array(
765 + 'taxonomy' => 'course_tag',
766 + 'field' => 'term_id',
767 + 'terms' => $term_ids,
768 + 'operator' => 'IN',
769 + );
770 + }
783 771
784 - // Set custom posts per page
785 - if ( $this->_is_archive() ) {
786 - $is_archive_course = 1;
787 - }
772 + $q->set( 'tax_query', $tax_query );
773 + // End Tax query
788 774
789 - $apply_lazy_load_for_theme = apply_filters( 'lp/page/courses/query/lazy_load', false );
775 + // Author query
776 + if ( isset( $_REQUEST['c_author'] ) ) {
777 + $author_ids = LP_Helper::sanitize_params_submitted( $_REQUEST['c_author'] );
778 + $q->set( 'author__in', $author_ids );
779 + }
780 + // End Author query
790 781
791 - if ( $is_archive_course ) {
792 - if ( ( LP_Settings_Courses::is_ajax_load_courses() && ! LP_Settings_Courses::is_no_load_ajax_first_courses() ) ) {
793 - LP()->template( 'course' )->remove_callback( 'learn-press/after-courses-loop', 'loop/course/pagination.php', 10 );
794 - /**
795 - * If page is archive course - query set posts_per_page = 1
796 - * For fastest - because when page loaded - call API to load list courses
797 - *
798 - * Current, apply only for LP, not apply for theme Thimpress, because theme override
799 - */
800 - $q->set( 'posts_per_page', 1 );
801 - $q->set( 'posts_per_archive_page', 1 );
802 - $q->set( 'nopaging', true );
803 - } else {
804 - $filter = new LP_Course_Filter();
805 - $filter->only_fields = [ 'ID' ];
806 - $filter->max_limit = $filter->limit = 1000;
807 - $is_need_check_in_arr = false;
808 - $limit = LP_Settings::get_option( 'archive_course_limit', 6 );
782 + // Order query
783 + if ( isset( $_REQUEST['order_by'] ) ) {
784 + $order_by = LP_Helper::sanitize_params_submitted( $_REQUEST['order_by'] );
785 + $order = 'DESC';
809 786
810 - $q->set( 'posts_per_page', $limit );
811 - // $q->set( 'cache_results', true ); // it default true
787 + switch ( $order_by ) {
788 + case 'post_title':
789 + $order_by = 'title';
790 + $order = 'ASC';
791 + break;
792 + case 'popular':
793 + $filter->order_by = 'popular';
794 + $order_by = 'post__in';
795 + $is_need_check_in_arr = true;
796 + break;
797 + default:
798 + $order_by = 'date';
799 + break;
800 + }
812 801
813 - // Search courses by keyword
814 - // $q->set( 's', $_REQUEST['c_search'] ?? '' );
815 - if ( ! empty( $_REQUEST['c_search'] ) ) {
816 - $filter->post_title = LP_Helper::sanitize_params_submitted( $_REQUEST['c_search'] );
817 - $is_need_check_in_arr = true;
818 - }
819 -
820 - $author_ids_str = LP_Helper::sanitize_params_submitted( $_REQUEST['c_authors'] ?? 0 );
821 - if ( ! empty( $author_ids_str ) ) {
822 - $q->set( 'author', $author_ids_str );
823 - }
824 -
825 - // Meta query
826 - $meta_query = [];
827 - if ( isset( $_REQUEST['sort_by'] ) ) {
828 - $sort_by = LP_Helper::sanitize_params_submitted( $_REQUEST['sort_by'] );
829 - if ( 'on_paid' === $sort_by ) {
830 - $meta_query[] = array(
831 - 'key' => '_lp_price',
832 - 'value' => 0,
833 - 'compare' => '>',
834 - );
802 + $q->set( 'orderby', $order_by );
803 + $q->set( 'order', $order );
835 804 }
836 805
837 - if ( 'on_free' === $sort_by ) {
838 - $meta_query[] = array(
839 - 'key' => '_lp_price',
840 - 'value' => 0,
841 - 'compare' => '=',
842 - );
806 + if ( $is_need_check_in_arr ) {
807 + $posts_in = Courses::get_courses( $filter );
808 + if ( ! empty( $posts_in ) ) {
809 + $posts_in = LP_Database::get_values_by_key( $posts_in );
810 + $q->set( 'post__in', $posts_in );
811 + } else {
812 + $q->set( 'post__in', 0 );
813 + }
843 814 }
844 - }
845 - $q->set( 'meta_query', $meta_query );
846 - // End Meta query
847 815
848 - // Tax query
849 - $tax_query = [];
850 - $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $_REQUEST['term_id'] ?? '' ) );
851 - if ( ! empty( $term_ids_str ) ) {
852 - $term_ids = explode( ',', $term_ids_str );
853 -
854 - $tax_query[] = array(
855 - 'taxonomy' => 'course_category',
856 - 'field' => 'term_id',
857 - 'terms' => $term_ids,
858 - 'operator' => 'IN',
859 - );
816 + $q = apply_filters( 'lp/page-courses/query/legacy', $q );
860 817 }
861 818
862 - $q->set( 'tax_query', $tax_query );
863 - // End Tax query
819 + return $q;
820 + }
864 821
865 - // Author query
866 - if ( isset( $_REQUEST['c_author'] ) ) {
867 - $author_ids = LP_Helper::sanitize_params_submitted( $_REQUEST['c_author'] );
868 - $q->set( 'author__in', $author_ids );
869 - }
870 - // End Author query
822 + // Exclude item not assign
823 + if ( $q->is_search() ) {
824 + return $q;
825 + }
871 826
872 - // Order query
873 - if ( isset( $_REQUEST['order_by'] ) ) {
874 - $order_by = LP_Helper::sanitize_params_submitted( $_REQUEST['order_by'] );
875 - $order = 'DESC';
827 + // Handle 404 if user are viewing course item directly.
828 + $this->set_link_item_course_default_wp_to_page_404( $q );
876 829
877 - switch ( $order_by ) {
878 - case 'post_title':
879 - $order_by = 'title';
880 - $order = 'ASC';
881 - break;
882 - case 'popular':
883 - $filter->order_by = 'popular';
884 - $order_by = 'post__in';
885 - $is_need_check_in_arr = true;
886 - break;
887 - default:
888 - $order_by = 'date';
889 - break;
890 - }
891 -
892 - $q->set( 'orderby', $order_by );
893 - $q->set( 'order', $order );
830 + // set 404 if viewing single instructor but not logged
831 + $slug_instructor = get_query_var( 'instructor_name' );
832 + if ( get_query_var( 'is_single_instructor' ) ) {
833 + if ( empty( $slug_instructor ) && ! is_user_logged_in() ) {
834 + self::set_page_404();
894 835 }
895 -
896 - if ( $is_need_check_in_arr ) {
897 - $posts_in = LP_Course::get_courses( $filter );
898 - if ( ! empty( $posts_in ) ) {
899 - $posts_in = LP_Database::get_values_by_key( $posts_in );
900 - $q->set( 'post__in', $posts_in );
901 - } else {
902 - $q->set( 'post__in', 0 );
903 - }
904 - }
905 -
906 - $q = apply_filters( 'lp/page-courses/query/legacy', $q );
907 836 }
837 + } catch ( Throwable $e ) {
838 + error_log( $e->getMessage() );
908 839 }
909 840
910 841 return $q;
911 842 }
@@ -915,19 +846,28 @@
915 846 * Example: http://example.com/lesson/slug-lesson
916 847 * Apply for user not admin, instructor, co-instructor
917 848 *
918 849 * @param WP_Query $q
850 + *
919 851 * @editor tungnx
920 852 * @since 3.2.7.5
921 853 */
922 854 public function set_link_item_course_default_wp_to_page_404( $q ) {
923 - if ( ! $q->is_main_query() || is_admin() ) {
924 - return $q;
855 + $post_type_apply_404 = apply_filters(
856 + 'lp/page-controller/',
857 + array(
858 + LP_LESSON_CPT,
859 + LP_QUIZ_CPT,
860 + LP_QUESTION_CPT,
861 + 'lp_assignment',
862 + )
863 + );
864 +
865 + if ( ! isset( $q->query_vars['post_type'] ) || ! in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
866 + return;
925 867 }
926 868
927 - $post_type_apply_404 = array( LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, 'lp_assignment' );
928 -
929 - if ( isset( $q->query_vars['post_type'] ) && in_array( $q->query_vars['post_type'], $post_type_apply_404 ) ) {
869 + try {
930 870 $flag_load_404 = true;
931 871 $user = wp_get_current_user();
932 872 $post_author = 0;
933 873
@@ -953,80 +893,295 @@
953 893
954 894 $flag_load_404 = apply_filters( 'learnpress/page/set-link-item-course-404', $flag_load_404, $post_author, $user );
955 895
956 896 if ( $flag_load_404 ) {
957 - learn_press_404_page();
897 + self::set_page_404();
958 898 }
899 + } catch ( Throwable $e ) {
900 + error_log( $e->getMessage() );
959 901 }
960 902 }
961 903
962 904 /**
963 - * @depecated 4.1.6.9.2
905 + * Get page current on frontend
906 + *
907 + * @return string
908 + * @since 3.2.8
909 + * @author tungnx
964 910 */
965 - /*public function the_content_callback( $content ) {
966 - if ( $this->_archive_contents ) {
967 - preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content, $results );
968 - $this->_shortcode_exists = ! empty( $results );
969 - if ( $this->_shortcode_exists ) {
970 - $this->_shortcode_tag = $results[0];
971 - $content = str_replace( $this->_shortcode_tag, $this->_archive_contents, $content );
911 + public static function page_current(): string {
912 + /**
913 + * @var WP_Query $wp_query
914 + */
915 + global $wp_query;
916 +
917 + // Course Builder page detection
918 + if ( self::is_page_course_builder() ) {
919 + return LP_PAGE_COURSE_BUILDER;
920 + }
921 +
922 + if ( ! is_object( $wp_query ) || ! $wp_query->get_queried_object() ) {
923 + return '';
924 + }
925 +
926 + if ( self::is_page_checkout() ) {
927 + return LP_PAGE_CHECKOUT;
928 + } elseif ( LP_Global::course_item_quiz() ) {
929 + return LP_PAGE_QUIZ;
930 + } elseif ( learn_press_is_course() && LP_Global::course_item() ) {
931 + return LP_PAGE_SINGLE_COURSE_CURRICULUM;
932 + } elseif ( self::is_page_courses() ) {
933 + return LP_PAGE_COURSES;
934 + } elseif ( learn_press_is_course() ) {
935 + return LP_PAGE_SINGLE_COURSE;
936 + } elseif ( self::is_page_become_a_teacher() ) {
937 + return LP_PAGE_BECOME_A_TEACHER;
938 + } elseif ( self::is_page_profile() ) {
939 + return LP_PAGE_PROFILE;
940 + } elseif ( learn_press_is_instructors() ) {
941 + return LP_PAGE_INSTRUCTORS;
942 + } elseif ( self::is_page_instructor() ) {
943 + return LP_PAGE_INSTRUCTOR;
944 + } else {
945 + return apply_filters( 'learnpress/page/current', '' );
946 + }
947 + }
948 +
949 + /**
950 + * Check is page viewing
951 + *
952 + * @param string $name
953 + *
954 + * @return bool
955 + */
956 + public static function page_is( string $name = '' ): bool {
957 + $page_id = learn_press_get_page_id( $name );
958 + if ( ! $page_id || 'page' !== get_post_type( $page_id ) ) {
959 + return false;
960 + }
961 +
962 + // If pages of LP set to homepage will return false
963 + $link_page = urldecode( get_the_permalink( $page_id ) );
964 + $home_url = home_url( '/' );
965 + if ( $home_url === $link_page ) {
966 + return false;
967 + }
968 +
969 + $page_profile_option = untrailingslashit( $link_page );
970 + $page_profile_option = str_replace( '/', '\/', $page_profile_option );
971 + $pattern = "/^$page_profile_option/";
972 + if ( preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
973 + return true;
974 + }
975 +
976 + return false;
977 + }
978 +
979 + /**
980 + * Check is page is single course
981 + *
982 + * @since 4.2.7.6
983 + * @version 1.0.0
984 + * @return bool
985 + */
986 + public static function is_page_single_course(): bool {
987 + static $flag;
988 + if ( ! is_null( $flag ) ) {
989 + return $flag;
990 + }
991 +
992 + try {
993 + $flag = is_singular( LP_COURSE_CPT );
994 + } catch ( Throwable $e ) {
995 + $flag = false;
996 + }
997 +
998 + return $flag;
999 + }
1000 +
1001 + /**
1002 + * Check is page courses
1003 + *
1004 + * @return bool
1005 + */
1006 + public static function is_page_courses(): bool {
1007 + static $flag;
1008 + if ( ! is_null( $flag ) ) {
1009 + return $flag;
1010 + }
1011 +
1012 + $is_tag = is_tax( LP_COURSE_TAXONOMY_TAG );
1013 + $is_category = is_tax( LP_COURSE_CATEGORY_TAX );
1014 +
1015 + if ( $is_category || $is_tag || is_post_type_archive( 'lp_course' ) ) {
1016 + $flag = true;
1017 + } else {
1018 + $page_courses_id = learn_press_get_page_id( 'courses' );
1019 + $page_courses_url = untrailingslashit( get_the_permalink( $page_courses_id ) );
1020 + if ( empty( $page_courses_url ) ) {
1021 + $page_courses_url = home_url( 'courses' );
1022 + }
1023 +
1024 + $page_courses_regex = str_replace( '/', '\/', $page_courses_url );
1025 + $pattern = '/' . $page_courses_regex . '\/?(page\/[0-9]*)?$/';
1026 + if ( preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
1027 + $flag = true;
972 1028 } else {
973 - $content .= $this->_archive_contents;
1029 + $flag = false;
974 1030 }
975 1031 }
976 1032
977 - return $content;
978 - }*/
1033 + return $flag;
1034 + }
979 1035
980 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 + /**
981 1098 * Check is page Become a teacher
982 1099 *
983 - * @return bool|mixed|void
1100 + * @return bool
984 1101 * @since 3.2.8
985 1102 * @author tungnx
986 1103 */
987 - public static function is_page_become_a_teacher() {
988 - $page_id = learn_press_get_page_id( 'become_a_teacher' );
1104 + public static function is_page_become_a_teacher(): bool {
1105 + return self::page_is( 'become_a_teacher' );
1106 + }
989 1107
990 - if ( $page_id && is_page( $page_id ) ) {
1108 + /**
1109 + * Check page is LP Ajax
1110 + *
1111 + * @return bool
1112 + * @since 4.2.7.7
1113 + */
1114 + public static function is_page_lp_ajax(): bool {
1115 + // If pages of LP set to homepage will return false
1116 + $pattern = '/lp-ajax-handle/';
1117 + if ( preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
991 1118 return true;
992 1119 }
993 1120
994 - return apply_filters( 'learnpress/is-page/become-a-teacher', false );
1121 + return false;
995 1122 }
996 1123
997 1124 /**
998 - * Get page current on frontend
1125 + * Redirect admin to course builder if hide instructor access admin screen
999 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 + *
1000 1165 * @return string
1001 - * @since 3.2.8
1002 - * @author tungnx
1166 + * @since 4.2.7.8
1167 + * @version 1.0.0
1003 1168 */
1004 - public static function page_current(): string {
1005 - if ( learn_press_is_checkout() ) {
1006 - return LP_PAGE_CHECKOUT;
1007 - } elseif ( LP_Global::course_item_quiz() ) {
1008 - return LP_PAGE_QUIZ;
1009 - } elseif ( learn_press_is_course() && is_single() && LP_Global::course_item() ) {
1010 - return LP_PAGE_SINGLE_COURSE_CURRICULUM;
1011 - } elseif ( learn_press_is_courses() ) {
1012 - return LP_PAGE_COURSES;
1013 - } elseif ( learn_press_is_course() ) {
1014 - return LP_PAGE_SINGLE_COURSE;
1015 - } elseif ( self::is_page_become_a_teacher() ) {
1016 - return LP_PAGE_BECOME_A_TEACHER;
1017 - } elseif ( learn_press_is_profile() ) {
1018 - return LP_PAGE_PROFILE;
1019 - } else {
1020 - return apply_filters( 'learnpress/page/current', '' );
1169 + public static function get_link_page( string $page_name, array $args = [], bool $no_cache = false ): string {
1170 + $page_link = learn_press_get_page_link( $page_name );
1171 +
1172 + if ( ! empty( $args ) ) {
1173 + $page_link = add_query_arg( $args, $page_link );
1021 1174 }
1175 +
1176 + if ( $no_cache ) {
1177 + $page_link = LP_Helper::get_link_no_cache( $page_link );
1178 + }
1179 +
1180 + return $page_link;
1022 1181 }
1023 1182
1024 1183 public static function instance() {
1025 - if ( is_admin() ) {
1026 - return null;
1027 - }
1028 -
1029 1184 if ( ! self::$_instance ) {
1030 1185 self::$_instance = new self();
1031 1186 }
1032 1187
@@ -1038,10 +1193,14 @@
1038 1193 *
1039 1194 * @editor tungnx
1040 1195 * @version 1.0.1
1041 1196 * @since 3.0.0
1197 + * @deprecated 4.1.7.3
1042 1198 */
1043 1199 public function learn_press_edit_admin_bar() {
1200 + _deprecated_function( __METHOD__, '4.1.7.3' );
1201 + return;
1202 +
1044 1203 global $wp_admin_bar;
1045 1204
1046 1205 $current_user = wp_get_current_user();
1047 1206
@@ -1049,11 +1208,11 @@
1049 1208 return;
1050 1209 }
1051 1210
1052 1211 $page_profile_id = learn_press_get_page_id( 'profile' );
1053 -
1054 1212 if ( $page_profile_id && get_post_status( $page_profile_id ) != 'trash' ) {
1055 1213 $user_id = $current_user->ID;
1214 + $profile = LP_Profile::instance( $user_id );
1056 1215
1057 1216 $wp_admin_bar->add_menu(
1058 1217 array(
1059 1218 'id' => 'course_profile',
@@ -1058,9 +1217,9 @@
1058 1217 array(
1059 1218 'id' => 'course_profile',
1060 1219 'parent' => 'user-actions',
1061 1220 'title' => get_the_title( $page_profile_id ),
1062 - 'href' => learn_press_user_profile_link( $user_id, false ),
1221 + 'href' => $profile->get_tab_link(),
1063 1222 )
1064 1223 );
1065 1224 }
1066 1225 }
@@ -1081,7 +1240,86 @@
1081 1240 }
1082 1241
1083 1242 return $send_no_cache_headers;
1084 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 + }
1085 1325 }
1086 -
1087 -return LP_Page_Controller::instance();