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/Models/Courses.php +496 -496 4.3.9.14.4.8 View file →
@@ -1,496 +1,496 @@
1 -<?php
2 -
3 -/**
4 - * Class Courses
5 - *
6 - * Handle all method about list courses
7 - *
8 - * @package LearnPress/Classes
9 - * @version 1.0.1
10 - * @since 4.2.5.4
11 - */
12 -
13 -namespace LearnPress\Models;
14 -
15 -use LearnPress\Databases\Course\CourseJsonDB;
16 -use LearnPress\Filters\Course\CourseJsonFilter;
17 -use LP_Cache;
18 -use LP_Course_DB;
19 -use LP_Course_Filter;
20 -use LP_Courses_Cache;
21 -use LP_Database;
22 -use LP_Debug;
23 -use LP_Helper;
24 -use LP_Settings;
25 -use Throwable;
26 -
27 -class Courses {
28 - /**
29 - * Count total courses free
30 - *
31 - * @param LP_Course_Filter $filter
32 - *
33 - * @return int
34 - * @since 4.2.5.4
35 - * @version 1.0.0
36 - */
37 - public static function count_course_free( LP_Course_Filter $filter ): int {
38 - // Check cache
39 - $lang = $_REQUEST['lang'] ?? '';
40 - $key_cache = 'count-courses-free-' . md5( json_encode( $filter ) . $lang );
41 - $count = LP_Cache::cache_load_first( 'get', $key_cache );
42 - if ( false !== $count ) {
43 - return $count;
44 - }
45 -
46 - $lp_courses_cache = new LP_Courses_Cache( true );
47 - $count = $lp_courses_cache->get_cache( $key_cache );
48 - if ( false !== $count ) {
49 - LP_Cache::cache_load_first( 'set', $key_cache, $count );
50 -
51 - return $count;
52 - }
53 -
54 - $lp_course_db = LP_Course_DB::getInstance();
55 - $count = $lp_course_db->count_course_free( $filter );
56 -
57 - // Set cache
58 - $lp_courses_cache->set_cache( $key_cache, $count );
59 - $lp_courses_cache_keys = new LP_Courses_Cache( true );
60 - $lp_courses_cache_keys->save_cache_keys_count_courses_free( $key_cache );
61 - LP_Cache::cache_load_first( 'set', $key_cache, $count );
62 -
63 - return (int) $count;
64 - }
65 -
66 - /**
67 - * Handle params before query courses
68 - *
69 - * @param array $param
70 - * @param LP_Course_Filter $filter
71 - *
72 - * @return void
73 - * @version 1.0.3
74 - * @since 4.2.3.3 move from class LP_Course
75 - */
76 - public static function handle_params_for_query_courses( LP_Course_Filter &$filter, array $param = [] ) {
77 - $filter->page = absint( $param['paged'] ?? 1 );
78 - $filter->post_title = LP_Helper::sanitize_params_submitted( trim( $param['c_search'] ?? '' ) );
79 -
80 - // Get Columns
81 - $fields_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_fields'] ?? '' ) );
82 - if ( ! empty( $fields_str ) ) {
83 - $fields = explode( ',', $fields_str );
84 - foreach ( $fields as $key => $field ) {
85 - $fields[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
86 - }
87 - $filter->fields = $fields;
88 - }
89 -
90 - // Get only columns
91 - $fields_only_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_only_fields'] ?? '' ) );
92 - if ( ! empty( $fields_only_str ) ) {
93 - $fields_only = explode( ',', $fields_only_str );
94 - foreach ( $fields_only as $key => $field ) {
95 - $fields_only[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
96 - }
97 - $filter->only_fields = $fields_only;
98 - }
99 -
100 - // Exclude Columns
101 - $fields_exclude_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_exclude_fields'] ?? '' ) );
102 - if ( ! empty( $fields_exclude_str ) ) {
103 - $fields_exclude = explode( ',', $fields_exclude_str );
104 - $filter->exclude_fields = $fields_exclude;
105 - }
106 -
107 - // Find by ids
108 - $course_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['ids'] ?? '' ) );
109 - if ( ! empty( $course_ids_str ) ) {
110 - $course_ids = explode( ',', $course_ids_str );
111 - $filter->post_ids = $course_ids;
112 - }
113 -
114 - // Author
115 - $c_author = LP_Helper::sanitize_params_submitted( $param['c_author'] ?? 0 );
116 - if ( ! empty( $c_author ) ) {
117 - $filter->post_author = $c_author;
118 - }
119 - $author_ids_str = LP_Helper::sanitize_params_submitted( $param['c_authors'] ?? '' );
120 - if ( ! empty( $author_ids_str ) ) {
121 - $author_ids = explode( ',', $author_ids_str );
122 - $filter->post_authors = $author_ids;
123 - }
124 -
125 - // Find by status
126 - $post_status = LP_Helper::sanitize_params_submitted( $param['c_status'] ?? '' );
127 - if ( ! empty( $post_status ) ) {
128 - if ( 'all' !== $post_status ) {
129 - $filter->post_status = explode( ',', $post_status );
130 - }
131 - } else {
132 - $filter->post_status = [ 'publish' ];
133 - }
134 -
135 - /**
136 - * Sort by
137 - * 1. on_sale
138 - * 2. on_free
139 - * 3. on_paid
140 - * 4. on_feature
141 - */
142 - if ( ! empty( $param['sort_by'] ) ) {
143 - $filter->sort_by[] = $param['sort_by'];
144 - }
145 -
146 - // Sort by level
147 - $levels_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_level'] ?? '' ) );
148 - if ( ! empty( $levels_str ) ) {
149 - $levels = explode( ',', $levels_str );
150 - if ( in_array( 'all', $levels ) ) {
151 - $levels[] = '';
152 - }
153 - $filter->levels = $levels;
154 - }
155 -
156 - // Sort by type (oline/offline)
157 - $course_type = LP_Helper::sanitize_params_submitted( urldecode( $param['c_type'] ?? '' ) );
158 - if ( ! empty( $course_type ) ) {
159 - $course_type = explode( ',', $course_type );
160 - if ( in_array( 'online', $course_type ) && in_array( 'offline', $course_type ) ) {
161 - $filter->type = 'all';
162 - } else {
163 - $filter->type = $course_type[0];
164 - }
165 - }
166 -
167 - // Check is in category page.
168 - if ( ! empty( $param['page_term_id_current'] ) && empty( $param['term_id'] ) ) {
169 - $filter->term_ids[] = $param['page_term_id_current'];
170 - } // Check is in tag page.
171 - elseif ( ! empty( $param['page_tag_id_current'] ) && empty( $param['tag_id'] ) ) {
172 - $filter->tag_ids[] = $param['page_tag_id_current'];
173 - }
174 -
175 - // Find by category
176 - $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['term_id'] ?? '' ) );
177 - if ( ! empty( $term_ids_str ) ) {
178 - $term_ids = explode( ',', $term_ids_str );
179 - $filter->term_ids = array_merge( $filter->term_ids, $term_ids );
180 - }
181 -
182 - // Find by tag
183 - $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['tag_id'] ?? '' ) );
184 - if ( ! empty( $tag_ids_str ) ) {
185 - $tag_ids = explode( ',', $tag_ids_str );
186 - $filter->tag_ids = array_merge( $filter->tag_ids, $tag_ids );
187 - }
188 -
189 - // Order by
190 - $filter->order_by = LP_Helper::sanitize_params_submitted( ! empty( $param['order_by'] ) ? $param['order_by'] : 'post_date', 'key' );
191 - $filter->order = LP_Helper::sanitize_params_submitted( ! empty( $param['order'] ) ? $param['order'] : 'DESC', 'key' );
192 - $filter->limit = $param['limit'] ?? LP_Settings::get_option( 'archive_course_limit', 10 );
193 -
194 - // For search suggest courses
195 - if ( ! empty( $param['c_suggest'] ) ) {
196 - $filter->only_fields = [ 'ID', 'post_title' ];
197 - $filter->limit = apply_filters( 'learn-press/rest-api/courses/suggest-limit', 10 );
198 - }
199 -
200 - $return_type = $param['return_type'] ?? 'html';
201 - if ( 'json' !== $return_type ) {
202 - $filter->only_fields = array( 'DISTINCT(ID) AS ID' );
203 - }
204 -
205 - do_action( 'learn-press/courses/handle_params_for_query_courses', $filter, $param );
206 - }
207 -
208 - /**
209 - * Get list course
210 - * Order By: price, title, rating, date ...
211 - * Order: ASC, DES
212 - *
213 - * @param LP_Course_Filter $filter
214 - * @param int $total_rows
215 - *
216 - * @return object|null|string|int
217 - * @author tungnx
218 - * @version 1.0.1
219 - * @sicne 4.1.5
220 - */
221 - public static function get_courses( LP_Course_Filter $filter, int &$total_rows = 0 ) {
222 - $lp_course_db = LP_Course_DB::getInstance();
223 -
224 - try {
225 - // Order by
226 - switch ( $filter->order_by ) {
227 - case 'price':
228 - case 'price_low':
229 - if ( 'price_low' === $filter->order_by ) {
230 - $filter->order = 'ASC';
231 - } else {
232 - $filter->order = 'DESC';
233 - }
234 -
235 - $filter = $lp_course_db->get_courses_order_by_price( $filter );
236 - break;
237 - case 'popular':
238 - $filter = $lp_course_db->get_courses_order_by_popular( $filter );
239 - break;
240 - case 'post_title':
241 - $filter->order = 'ASC';
242 - break;
243 - case 'post_title_desc':
244 - $filter->order_by = 'post_title';
245 - $filter->order = 'DESC';
246 - break;
247 - case 'menu_order':
248 - $filter->order_by = 'menu_order';
249 - $filter->order = 'ASC';
250 - break;
251 - default:
252 - $filter = apply_filters( 'lp/courses/filter/order_by/' . $filter->order_by, $filter );
253 - break;
254 - }
255 -
256 - // Sort by
257 - $filter->sort_by = (array) $filter->sort_by;
258 - foreach ( $filter->sort_by as $sort_by ) {
259 - $filter_tmp = clone $filter;
260 - $filter_tmp->only_fields = array( 'DISTINCT(ID)' );
261 - $filter_tmp->return_string_query = true;
262 -
263 - switch ( $sort_by ) {
264 - case 'on_sale':
265 - $filter_tmp = $lp_course_db->get_courses_sort_by_sale( $filter_tmp );
266 - break;
267 - case 'on_free':
268 - $filter_tmp = $lp_course_db->get_courses_sort_by_free( $filter_tmp );
269 - break;
270 - case 'on_paid':
271 - $filter_tmp = $lp_course_db->get_courses_sort_by_paid( $filter_tmp );
272 - break;
273 - case 'on_feature':
274 - $filter_tmp = $lp_course_db->get_courses_sort_by_feature( $filter_tmp );
275 - break;
276 - default:
277 - $filter_tmp = apply_filters( 'lp/courses/filter/sort_by/' . $sort_by, $filter_tmp );
278 - break;
279 - }
280 -
281 - $query_courses_str = $lp_course_db->get_courses( $filter_tmp );
282 -
283 - $filter->where[] = "AND ID IN ({$query_courses_str})";
284 - }
285 -
286 - // Query get results
287 - $filter = apply_filters( 'lp/courses/filter', $filter );
288 - $courses = LP_Course_DB::getInstance()->get_courses( $filter, $total_rows );
289 - } catch ( Throwable $e ) {
290 - $courses = [];
291 - error_log( __FUNCTION__ . ': ' . $e->getMessage() );
292 - }
293 -
294 - return $courses;
295 - }
296 -
297 - /**
298 - * Handle params before query list courses on table learnpress_courses
299 - *
300 - * @param CourseJsonFilter $filter
301 - * @param array $param
302 - *
303 - * @return void
304 - * @since 4.3.2.3
305 - * @version 1.0.0
306 - */
307 - public static function handle_params_for_query_list_courses( CourseJsonFilter &$filter, array $param = [] ) {
308 - $filter->page = absint( $param['paged'] ?? 1 );
309 - $filter->post_title = LP_Helper::sanitize_params_submitted( trim( $param['c_search'] ?? '' ) );
310 -
311 - // Get Columns
312 - $fields_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_fields'] ?? '' ) );
313 - if ( ! empty( $fields_str ) ) {
314 - $fields = explode( ',', $fields_str );
315 - foreach ( $fields as $key => $field ) {
316 - $fields[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
317 - }
318 - $filter->fields = $fields;
319 - }
320 -
321 - // Get only columns
322 - $fields_only_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_only_fields'] ?? '' ) );
323 - if ( ! empty( $fields_only_str ) ) {
324 - $fields_only = explode( ',', $fields_only_str );
325 - foreach ( $fields_only as $key => $field ) {
326 - $fields_only[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
327 - }
328 - $filter->only_fields = $fields_only;
329 - }
330 -
331 - // Exclude Columns
332 - $fields_exclude_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_exclude_fields'] ?? '' ) );
333 - if ( ! empty( $fields_exclude_str ) ) {
334 - $fields_exclude = explode( ',', $fields_exclude_str );
335 - $filter->exclude_fields = $fields_exclude;
336 - }
337 -
338 - // Find by ids
339 - $course_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['ids'] ?? '' ) );
340 - if ( ! empty( $course_ids_str ) ) {
341 - $course_ids = explode( ',', $course_ids_str );
342 - $filter->ids = $course_ids;
343 - }
344 -
345 - // Author
346 - $c_author = LP_Helper::sanitize_params_submitted( $param['c_author'] ?? 0 );
347 - if ( ! empty( $c_author ) ) {
348 - $filter->post_author = $c_author;
349 - }
350 - $author_ids_str = LP_Helper::sanitize_params_submitted( $param['c_authors'] ?? '' );
351 - if ( ! empty( $author_ids_str ) ) {
352 - $author_ids = explode( ',', $author_ids_str );
353 - $filter->post_authors = $author_ids;
354 - }
355 -
356 - // Find by status
357 - $post_status = LP_Helper::sanitize_params_submitted( $param['c_status'] ?? '' );
358 - if ( ! empty( $post_status ) ) {
359 - if ( 'all' !== $post_status ) {
360 - $filter->post_status = explode( ',', $post_status );
361 - }
362 - }
363 -
364 - // Type price
365 - if ( ! empty( $param['c_type_price'] ) ) {
366 - $filter->type_price = explode( ',', LP_Helper::sanitize_params_submitted( urldecode( $param['c_type_price'] ) ) );
367 - }
368 -
369 - // On sale
370 - if ( isset( $param['on_sale'] ) ) {
371 - $filter->is_sale = 1;
372 - }
373 -
374 - // On feature
375 - if ( isset( $param['on_feature'] ) ) {
376 - $filter->is_feature = 1;
377 - }
378 -
379 - // Sort by level
380 - $levels_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_level'] ?? '' ) );
381 - if ( ! empty( $levels_str ) ) {
382 - $levels = explode( ',', $levels_str );
383 - if ( in_array( 'all', $levels ) ) {
384 - $levels[] = '';
385 - }
386 - $filter->levels = $levels;
387 - }
388 -
389 - // Sort by type (oline/offline)
390 - $course_type = LP_Helper::sanitize_params_submitted( urldecode( $param['c_type'] ?? '' ) );
391 - if ( ! empty( $course_type ) ) {
392 - $course_type = explode( ',', $course_type );
393 - if ( in_array( 'online', $course_type ) && in_array( 'offline', $course_type ) ) {
394 - $filter->type = 'all';
395 - } else {
396 - $filter->type = $course_type[0];
397 - }
398 - }
399 -
400 - // Check is in category page.
401 - if ( ! empty( $param['page_term_id_current'] ) && empty( $param['term_id'] ) ) {
402 - $filter->term_ids[] = $param['page_term_id_current'];
403 - } // Check is in tag page.
404 - elseif ( ! empty( $param['page_tag_id_current'] ) && empty( $param['tag_id'] ) ) {
405 - $filter->tag_ids[] = $param['page_tag_id_current'];
406 - }
407 -
408 - // Find by category
409 - $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['term_id'] ?? '' ) );
410 - if ( ! empty( $term_ids_str ) ) {
411 - $term_ids = explode( ',', $term_ids_str );
412 - $filter->term_ids = array_merge( $filter->term_ids, $term_ids );
413 - }
414 -
415 - // Find by tag
416 - $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['tag_id'] ?? '' ) );
417 - if ( ! empty( $tag_ids_str ) ) {
418 - $tag_ids = explode( ',', $tag_ids_str );
419 - $filter->tag_ids = array_merge( $filter->tag_ids, $tag_ids );
420 - }
421 -
422 - // Order by
423 - $filter->order_by = LP_Helper::sanitize_params_submitted( ! empty( $param['order_by'] ) ? $param['order_by'] : 'post_date_gmt', 'key' );
424 - $filter->order = LP_Helper::sanitize_params_submitted( ! empty( $param['order'] ) ? $param['order'] : 'DESC', 'key' );
425 - $filter->limit = $param['limit'] ?? LP_Settings::get_option( 'archive_course_limit', 10 );
426 -
427 - // For search suggest courses
428 - if ( ! empty( $param['c_suggest'] ) ) {
429 - $filter->only_fields = [ 'ID', 'post_title' ];
430 - $filter->limit = apply_filters( 'learn-press/rest-api/courses/suggest-limit', 10 );
431 - }
432 -
433 - do_action( 'learn-press/courses/handle_params_for_query_list_courses', $filter, $param );
434 - }
435 -
436 - /**
437 - * Get list courses on table learnpress_courses
438 - *
439 - * @param CourseJsonFilter $filter
440 - * @param int $total_rows
441 - *
442 - * @return array
443 - * @since 4.3.2.3
444 - * @version 1.0.0
445 - */
446 - public static function get_list_courses( CourseJsonFilter $filter, int &$total_rows = 0 ): array {
447 - $db = CourseJsonDB::getInstance();
448 -
449 - try {
450 - $is_order_by_popular = 'popular' === $filter->order_by;
451 -
452 - // Order by
453 - switch ( $filter->order_by ) {
454 - case 'price':
455 - case 'price_low':
456 - if ( 'price_low' === $filter->order_by ) {
457 - $filter->order = 'ASC';
458 - } else {
459 - $filter->order = 'DESC';
460 - }
461 -
462 - $filter->order_by = 'price_to_sort';
463 - break;
464 - case 'popular':
465 - $filter = $db->get_courses_order_by_popular( $filter );
466 - break;
467 - case 'post_title':
468 - $filter->order = 'ASC';
469 - break;
470 - case 'post_title_desc':
471 - $filter->order_by = 'post_title';
472 - $filter->order = 'DESC';
473 - break;
474 - case 'menu_order':
475 - $filter->order_by = 'menu_order';
476 - $filter->order = 'ASC';
477 - break;
478 - default:
479 - $filter = apply_filters( 'lp/courses-json/filter/order_by/' . $filter->order_by, $filter );
480 - break;
481 - }
482 -
483 - // Query get results
484 - /**
485 - * @var CourseJsonFilter $filter
486 - */
487 - $filter = apply_filters( 'lp/courses-json/filter', $filter );
488 - $courses = $db->get_courses( $filter, $total_rows );
489 - } catch ( Throwable $e ) {
490 - $courses = [];
491 - LP_Debug::error_log( $e );
492 - }
493 -
494 - return $courses;
495 - }
496 -}
1 +<?php
2 +
3 +/**
4 + * Class Courses
5 + *
6 + * Handle all method about list courses
7 + *
8 + * @package LearnPress/Classes
9 + * @version 1.0.1
10 + * @since 4.2.5.4
11 + */
12 +
13 +namespace LearnPress\Models;
14 +
15 +use LearnPress\Databases\Course\CourseJsonDB;
16 +use LearnPress\Filters\Course\CourseJsonFilter;
17 +use LP_Cache;
18 +use LP_Course_DB;
19 +use LP_Course_Filter;
20 +use LP_Courses_Cache;
21 +use LP_Database;
22 +use LP_Debug;
23 +use LP_Helper;
24 +use LP_Settings;
25 +use Throwable;
26 +
27 +class Courses {
28 + /**
29 + * Count total courses free
30 + *
31 + * @param LP_Course_Filter $filter
32 + *
33 + * @return int
34 + * @since 4.2.5.4
35 + * @version 1.0.0
36 + */
37 + public static function count_course_free( LP_Course_Filter $filter ): int {
38 + // Check cache
39 + $lang = $_REQUEST['lang'] ?? '';
40 + $key_cache = 'count-courses-free-' . md5( json_encode( $filter ) . $lang );
41 + $count = LP_Cache::cache_load_first( 'get', $key_cache );
42 + if ( false !== $count ) {
43 + return $count;
44 + }
45 +
46 + $lp_courses_cache = new LP_Courses_Cache( true );
47 + $count = $lp_courses_cache->get_cache( $key_cache );
48 + if ( false !== $count ) {
49 + LP_Cache::cache_load_first( 'set', $key_cache, $count );
50 +
51 + return $count;
52 + }
53 +
54 + $lp_course_db = LP_Course_DB::getInstance();
55 + $count = $lp_course_db->count_course_free( $filter );
56 +
57 + // Set cache
58 + $lp_courses_cache->set_cache( $key_cache, $count );
59 + $lp_courses_cache_keys = new LP_Courses_Cache( true );
60 + $lp_courses_cache_keys->save_cache_keys_count_courses_free( $key_cache );
61 + LP_Cache::cache_load_first( 'set', $key_cache, $count );
62 +
63 + return (int) $count;
64 + }
65 +
66 + /**
67 + * Handle params before query courses
68 + *
69 + * @param array $param
70 + * @param LP_Course_Filter $filter
71 + *
72 + * @return void
73 + * @version 1.0.3
74 + * @since 4.2.3.3 move from class LP_Course
75 + */
76 + public static function handle_params_for_query_courses( LP_Course_Filter &$filter, array $param = [] ) {
77 + $filter->page = absint( $param['paged'] ?? 1 );
78 + $filter->post_title = LP_Helper::sanitize_params_submitted( trim( $param['c_search'] ?? '' ) );
79 +
80 + // Get Columns
81 + $fields_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_fields'] ?? '' ) );
82 + if ( ! empty( $fields_str ) ) {
83 + $fields = explode( ',', $fields_str );
84 + foreach ( $fields as $key => $field ) {
85 + $fields[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
86 + }
87 + $filter->fields = $fields;
88 + }
89 +
90 + // Get only columns
91 + $fields_only_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_only_fields'] ?? '' ) );
92 + if ( ! empty( $fields_only_str ) ) {
93 + $fields_only = explode( ',', $fields_only_str );
94 + foreach ( $fields_only as $key => $field ) {
95 + $fields_only[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
96 + }
97 + $filter->only_fields = $fields_only;
98 + }
99 +
100 + // Exclude Columns
101 + $fields_exclude_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_exclude_fields'] ?? '' ) );
102 + if ( ! empty( $fields_exclude_str ) ) {
103 + $fields_exclude = explode( ',', $fields_exclude_str );
104 + $filter->exclude_fields = $fields_exclude;
105 + }
106 +
107 + // Find by ids
108 + $course_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['ids'] ?? '' ) );
109 + if ( ! empty( $course_ids_str ) ) {
110 + $course_ids = explode( ',', $course_ids_str );
111 + $filter->post_ids = $course_ids;
112 + }
113 +
114 + // Author
115 + $c_author = LP_Helper::sanitize_params_submitted( $param['c_author'] ?? 0 );
116 + if ( ! empty( $c_author ) ) {
117 + $filter->post_author = $c_author;
118 + }
119 + $author_ids_str = LP_Helper::sanitize_params_submitted( $param['c_authors'] ?? '' );
120 + if ( ! empty( $author_ids_str ) ) {
121 + $author_ids = explode( ',', $author_ids_str );
122 + $filter->post_authors = $author_ids;
123 + }
124 +
125 + // Find by status
126 + $post_status = LP_Helper::sanitize_params_submitted( $param['c_status'] ?? '' );
127 + if ( ! empty( $post_status ) ) {
128 + if ( 'all' !== $post_status ) {
129 + $filter->post_status = explode( ',', $post_status );
130 + }
131 + } else {
132 + $filter->post_status = [ 'publish' ];
133 + }
134 +
135 + /**
136 + * Sort by
137 + * 1. on_sale
138 + * 2. on_free
139 + * 3. on_paid
140 + * 4. on_feature
141 + */
142 + if ( ! empty( $param['sort_by'] ) ) {
143 + $filter->sort_by[] = $param['sort_by'];
144 + }
145 +
146 + // Sort by level
147 + $levels_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_level'] ?? '' ) );
148 + if ( ! empty( $levels_str ) ) {
149 + $levels = explode( ',', $levels_str );
150 + if ( in_array( 'all', $levels ) ) {
151 + $levels[] = '';
152 + }
153 + $filter->levels = $levels;
154 + }
155 +
156 + // Sort by type (oline/offline)
157 + $course_type = LP_Helper::sanitize_params_submitted( urldecode( $param['c_type'] ?? '' ) );
158 + if ( ! empty( $course_type ) ) {
159 + $course_type = explode( ',', $course_type );
160 + if ( in_array( 'online', $course_type ) && in_array( 'offline', $course_type ) ) {
161 + $filter->type = 'all';
162 + } else {
163 + $filter->type = $course_type[0];
164 + }
165 + }
166 +
167 + // Check is in category page.
168 + if ( ! empty( $param['page_term_id_current'] ) && empty( $param['term_id'] ) ) {
169 + $filter->term_ids[] = $param['page_term_id_current'];
170 + } // Check is in tag page.
171 + elseif ( ! empty( $param['page_tag_id_current'] ) && empty( $param['tag_id'] ) ) {
172 + $filter->tag_ids[] = $param['page_tag_id_current'];
173 + }
174 +
175 + // Find by category
176 + $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['term_id'] ?? '' ) );
177 + if ( ! empty( $term_ids_str ) ) {
178 + $term_ids = explode( ',', $term_ids_str );
179 + $filter->term_ids = array_merge( $filter->term_ids, $term_ids );
180 + }
181 +
182 + // Find by tag
183 + $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['tag_id'] ?? '' ) );
184 + if ( ! empty( $tag_ids_str ) ) {
185 + $tag_ids = explode( ',', $tag_ids_str );
186 + $filter->tag_ids = array_merge( $filter->tag_ids, $tag_ids );
187 + }
188 +
189 + // Order by
190 + $filter->order_by = LP_Helper::sanitize_params_submitted( ! empty( $param['order_by'] ) ? $param['order_by'] : 'post_date', 'key' );
191 + $filter->order = LP_Helper::sanitize_params_submitted( ! empty( $param['order'] ) ? $param['order'] : 'DESC', 'key' );
192 + $filter->limit = $param['limit'] ?? LP_Settings::get_option( 'archive_course_limit', 10 );
193 +
194 + // For search suggest courses
195 + if ( ! empty( $param['c_suggest'] ) ) {
196 + $filter->only_fields = [ 'ID', 'post_title' ];
197 + $filter->limit = apply_filters( 'learn-press/rest-api/courses/suggest-limit', 10 );
198 + }
199 +
200 + $return_type = $param['return_type'] ?? 'html';
201 + if ( 'json' !== $return_type ) {
202 + $filter->only_fields = array( 'DISTINCT(ID) AS ID' );
203 + }
204 +
205 + do_action( 'learn-press/courses/handle_params_for_query_courses', $filter, $param );
206 + }
207 +
208 + /**
209 + * Get list course
210 + * Order By: price, title, rating, date ...
211 + * Order: ASC, DES
212 + *
213 + * @param LP_Course_Filter $filter
214 + * @param int $total_rows
215 + *
216 + * @return object|null|string|int
217 + * @author tungnx
218 + * @version 1.0.1
219 + * @sicne 4.1.5
220 + */
221 + public static function get_courses( LP_Course_Filter $filter, int &$total_rows = 0 ) {
222 + $lp_course_db = LP_Course_DB::getInstance();
223 +
224 + try {
225 + // Order by
226 + switch ( $filter->order_by ) {
227 + case 'price':
228 + case 'price_low':
229 + if ( 'price_low' === $filter->order_by ) {
230 + $filter->order = 'ASC';
231 + } else {
232 + $filter->order = 'DESC';
233 + }
234 +
235 + $filter = $lp_course_db->get_courses_order_by_price( $filter );
236 + break;
237 + case 'popular':
238 + $filter = $lp_course_db->get_courses_order_by_popular( $filter );
239 + break;
240 + case 'post_title':
241 + $filter->order = 'ASC';
242 + break;
243 + case 'post_title_desc':
244 + $filter->order_by = 'post_title';
245 + $filter->order = 'DESC';
246 + break;
247 + case 'menu_order':
248 + $filter->order_by = 'menu_order';
249 + $filter->order = 'ASC';
250 + break;
251 + default:
252 + $filter = apply_filters( 'lp/courses/filter/order_by/' . $filter->order_by, $filter );
253 + break;
254 + }
255 +
256 + // Sort by
257 + $filter->sort_by = (array) $filter->sort_by;
258 + foreach ( $filter->sort_by as $sort_by ) {
259 + $filter_tmp = clone $filter;
260 + $filter_tmp->only_fields = array( 'DISTINCT(ID)' );
261 + $filter_tmp->return_string_query = true;
262 +
263 + switch ( $sort_by ) {
264 + case 'on_sale':
265 + $filter_tmp = $lp_course_db->get_courses_sort_by_sale( $filter_tmp );
266 + break;
267 + case 'on_free':
268 + $filter_tmp = $lp_course_db->get_courses_sort_by_free( $filter_tmp );
269 + break;
270 + case 'on_paid':
271 + $filter_tmp = $lp_course_db->get_courses_sort_by_paid( $filter_tmp );
272 + break;
273 + case 'on_feature':
274 + $filter_tmp = $lp_course_db->get_courses_sort_by_feature( $filter_tmp );
275 + break;
276 + default:
277 + $filter_tmp = apply_filters( 'lp/courses/filter/sort_by/' . $sort_by, $filter_tmp );
278 + break;
279 + }
280 +
281 + $query_courses_str = $lp_course_db->get_courses( $filter_tmp );
282 +
283 + $filter->where[] = "AND ID IN ({$query_courses_str})";
284 + }
285 +
286 + // Query get results
287 + $filter = apply_filters( 'lp/courses/filter', $filter );
288 + $courses = LP_Course_DB::getInstance()->get_courses( $filter, $total_rows );
289 + } catch ( Throwable $e ) {
290 + $courses = [];
291 + error_log( __FUNCTION__ . ': ' . $e->getMessage() );
292 + }
293 +
294 + return $courses;
295 + }
296 +
297 + /**
298 + * Handle params before query list courses on table learnpress_courses
299 + *
300 + * @param CourseJsonFilter $filter
301 + * @param array $param
302 + *
303 + * @return void
304 + * @since 4.3.2.3
305 + * @version 1.0.0
306 + */
307 + public static function handle_params_for_query_list_courses( CourseJsonFilter &$filter, array $param = [] ) {
308 + $filter->page = absint( $param['paged'] ?? 1 );
309 + $filter->post_title = LP_Helper::sanitize_params_submitted( trim( $param['c_search'] ?? '' ) );
310 +
311 + // Get Columns
312 + $fields_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_fields'] ?? '' ) );
313 + if ( ! empty( $fields_str ) ) {
314 + $fields = explode( ',', $fields_str );
315 + foreach ( $fields as $key => $field ) {
316 + $fields[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
317 + }
318 + $filter->fields = $fields;
319 + }
320 +
321 + // Get only columns
322 + $fields_only_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_only_fields'] ?? '' ) );
323 + if ( ! empty( $fields_only_str ) ) {
324 + $fields_only = explode( ',', $fields_only_str );
325 + foreach ( $fields_only as $key => $field ) {
326 + $fields_only[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
327 + }
328 + $filter->only_fields = $fields_only;
329 + }
330 +
331 + // Exclude Columns
332 + $fields_exclude_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_exclude_fields'] ?? '' ) );
333 + if ( ! empty( $fields_exclude_str ) ) {
334 + $fields_exclude = explode( ',', $fields_exclude_str );
335 + $filter->exclude_fields = $fields_exclude;
336 + }
337 +
338 + // Find by ids
339 + $course_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['ids'] ?? '' ) );
340 + if ( ! empty( $course_ids_str ) ) {
341 + $course_ids = explode( ',', $course_ids_str );
342 + $filter->ids = $course_ids;
343 + }
344 +
345 + // Author
346 + $c_author = LP_Helper::sanitize_params_submitted( $param['c_author'] ?? 0 );
347 + if ( ! empty( $c_author ) ) {
348 + $filter->post_author = $c_author;
349 + }
350 + $author_ids_str = LP_Helper::sanitize_params_submitted( $param['c_authors'] ?? '' );
351 + if ( ! empty( $author_ids_str ) ) {
352 + $author_ids = explode( ',', $author_ids_str );
353 + $filter->post_authors = $author_ids;
354 + }
355 +
356 + // Find by status
357 + $post_status = LP_Helper::sanitize_params_submitted( $param['c_status'] ?? '' );
358 + if ( ! empty( $post_status ) ) {
359 + if ( 'all' !== $post_status ) {
360 + $filter->post_status = explode( ',', $post_status );
361 + }
362 + }
363 +
364 + // Type price
365 + if ( ! empty( $param['c_type_price'] ) ) {
366 + $filter->type_price = explode( ',', LP_Helper::sanitize_params_submitted( urldecode( $param['c_type_price'] ) ) );
367 + }
368 +
369 + // On sale
370 + if ( isset( $param['on_sale'] ) ) {
371 + $filter->is_sale = 1;
372 + }
373 +
374 + // On feature
375 + if ( isset( $param['on_feature'] ) ) {
376 + $filter->is_feature = 1;
377 + }
378 +
379 + // Sort by level
380 + $levels_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_level'] ?? '' ) );
381 + if ( ! empty( $levels_str ) ) {
382 + $levels = explode( ',', $levels_str );
383 + if ( in_array( 'all', $levels ) ) {
384 + $levels[] = '';
385 + }
386 + $filter->levels = $levels;
387 + }
388 +
389 + // Sort by type (oline/offline)
390 + $course_type = LP_Helper::sanitize_params_submitted( urldecode( $param['c_type'] ?? '' ) );
391 + if ( ! empty( $course_type ) ) {
392 + $course_type = explode( ',', $course_type );
393 + if ( in_array( 'online', $course_type ) && in_array( 'offline', $course_type ) ) {
394 + $filter->type = 'all';
395 + } else {
396 + $filter->type = $course_type[0];
397 + }
398 + }
399 +
400 + // Check is in category page.
401 + if ( ! empty( $param['page_term_id_current'] ) && empty( $param['term_id'] ) ) {
402 + $filter->term_ids[] = $param['page_term_id_current'];
403 + } // Check is in tag page.
404 + elseif ( ! empty( $param['page_tag_id_current'] ) && empty( $param['tag_id'] ) ) {
405 + $filter->tag_ids[] = $param['page_tag_id_current'];
406 + }
407 +
408 + // Find by category
409 + $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['term_id'] ?? '' ) );
410 + if ( ! empty( $term_ids_str ) ) {
411 + $term_ids = explode( ',', $term_ids_str );
412 + $filter->term_ids = array_merge( $filter->term_ids, $term_ids );
413 + }
414 +
415 + // Find by tag
416 + $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['tag_id'] ?? '' ) );
417 + if ( ! empty( $tag_ids_str ) ) {
418 + $tag_ids = explode( ',', $tag_ids_str );
419 + $filter->tag_ids = array_merge( $filter->tag_ids, $tag_ids );
420 + }
421 +
422 + // Order by
423 + $filter->order_by = LP_Helper::sanitize_params_submitted( ! empty( $param['order_by'] ) ? $param['order_by'] : 'post_date_gmt', 'key' );
424 + $filter->order = LP_Helper::sanitize_params_submitted( ! empty( $param['order'] ) ? $param['order'] : 'DESC', 'key' );
425 + $filter->limit = $param['limit'] ?? LP_Settings::get_option( 'archive_course_limit', 10 );
426 +
427 + // For search suggest courses
428 + if ( ! empty( $param['c_suggest'] ) ) {
429 + $filter->only_fields = [ 'ID', 'post_title' ];
430 + $filter->limit = apply_filters( 'learn-press/rest-api/courses/suggest-limit', 10 );
431 + }
432 +
433 + do_action( 'learn-press/courses/handle_params_for_query_list_courses', $filter, $param );
434 + }
435 +
436 + /**
437 + * Get list courses on table learnpress_courses
438 + *
439 + * @param CourseJsonFilter $filter
440 + * @param int $total_rows
441 + *
442 + * @return array
443 + * @since 4.3.2.3
444 + * @version 1.0.0
445 + */
446 + public static function get_list_courses( CourseJsonFilter $filter, int &$total_rows = 0 ): array {
447 + $db = CourseJsonDB::getInstance();
448 +
449 + try {
450 + $is_order_by_popular = 'popular' === $filter->order_by;
451 +
452 + // Order by
453 + switch ( $filter->order_by ) {
454 + case 'price':
455 + case 'price_low':
456 + if ( 'price_low' === $filter->order_by ) {
457 + $filter->order = 'ASC';
458 + } else {
459 + $filter->order = 'DESC';
460 + }
461 +
462 + $filter->order_by = 'price_to_sort';
463 + break;
464 + case 'popular':
465 + $filter = $db->get_courses_order_by_popular( $filter );
466 + break;
467 + case 'post_title':
468 + $filter->order = 'ASC';
469 + break;
470 + case 'post_title_desc':
471 + $filter->order_by = 'post_title';
472 + $filter->order = 'DESC';
473 + break;
474 + case 'menu_order':
475 + $filter->order_by = 'menu_order';
476 + $filter->order = 'ASC';
477 + break;
478 + default:
479 + $filter = apply_filters( 'lp/courses-json/filter/order_by/' . $filter->order_by, $filter );
480 + break;
481 + }
482 +
483 + // Query get results
484 + /**
485 + * @var CourseJsonFilter $filter
486 + */
487 + $filter = apply_filters( 'lp/courses-json/filter', $filter );
488 + $courses = $db->get_courses( $filter, $total_rows );
489 + } catch ( Throwable $e ) {
490 + $courses = [];
491 + LP_Debug::error_log( $e );
492 + }
493 +
494 + return $courses;
495 + }
496 +}