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/Databases/Course/CourseJsonDB.php +294 -294 4.3.9.14.4.8 View file →
@@ -1,294 +1,294 @@
1 -<?php
2 -
3 -namespace LearnPress\Databases\Course;
4 -
5 -use Exception;
6 -use LearnPress\Databases\DataBase;
7 -use LearnPress\Filters\Course\CourseJsonFilter;
8 -use LP_Helper;
9 -
10 -defined( 'ABSPATH' ) || exit();
11 -
12 -/**
13 - * Class CourseJsonDB
14 - *
15 - * Move from LP_Course_JSON_DB to here
16 - *
17 - * @since 4.3.2.3
18 - * @version 1.0.1
19 - */
20 -class CourseJsonDB extends DataBase {
21 - private static $_instance;
22 -
23 - protected function __construct() {
24 - parent::__construct();
25 - }
26 -
27 - public static function getInstance() {
28 - if ( is_null( self::$_instance ) ) {
29 - self::$_instance = new self();
30 - }
31 -
32 - return self::$_instance;
33 - }
34 -
35 - /**
36 - * Get Courses
37 - *
38 - * @param CourseJsonFilter $filter
39 - * @param int $total_rows return total_rows
40 - *
41 - * @return array|int|string|null
42 - * @throws Exception
43 - * @version 1.0.1
44 - * @since 4.2.6.9
45 - */
46 - public function get_courses( CourseJsonFilter $filter, int &$total_rows = 0 ) {
47 - $filter->fields = array_merge( $filter->all_fields, $filter->fields );
48 -
49 - if ( empty( $filter->collection ) ) {
50 - $filter->collection = $this->tb_lp_courses;
51 - }
52 -
53 - if ( empty( $filter->collection_alias ) ) {
54 - $filter->collection_alias = 'c';
55 - }
56 -
57 - $ca = $filter->collection_alias;
58 -
59 - // Find ID
60 - if ( ! empty( $filter->ID ) ) {
61 - $filter->where[] = $this->wpdb->prepare( "AND $ca.ID = %d", $filter->ID );
62 - }
63 -
64 - // Status
65 - $filter->post_status = (array) $filter->post_status;
66 - if ( ! empty( $filter->post_status ) ) {
67 - $post_status_format = LP_Helper::db_format_array( $filter->post_status, '%s' );
68 - $filter->where[] = $this->wpdb->prepare( "AND $ca.post_status IN (" . $post_status_format . ')', $filter->post_status );
69 - }
70 -
71 - // Exclude status auto-draft, because Admin of WP not show auto-draft in list post, so all front-end and back-end of LP also not show auto-draft
72 - if ( ! in_array( 'auto-draft', $filter->post_status, true ) ) {
73 - $filter->where[] = $this->wpdb->prepare( "AND $ca.post_status != %s", 'auto-draft' );
74 - }
75 -
76 - // Term ids
77 - if ( ! empty( $filter->term_ids ) ) {
78 - // Sanitize term ids
79 - $filter->term_ids = array_map( 'absint', $filter->term_ids );
80 - $term_ids_format = join( ',', $filter->term_ids );
81 - $filter->join[] = "INNER JOIN $this->tb_term_relationships AS r_term_p ON $ca.ID = r_term_p.object_id";
82 - $filter->join[] = "INNER JOIN $this->tb_term_taxonomy AS tx_p ON r_term_p.term_taxonomy_id = tx_p.term_taxonomy_id";
83 - $filter->where[] = "AND r_term_p.term_taxonomy_id IN ($term_ids_format)";
84 - $filter->where[] = $this->wpdb->prepare( 'AND tx_p.taxonomy = %s', $filter->taxonomy );
85 - }
86 -
87 - // Course ids
88 - if ( ! empty( $filter->ids ) ) {
89 - $ids = array_map( 'absint', $filter->ids );
90 - $ids_format = join( ',', $ids );
91 - $filter->where[] = "AND $ca.ID IN ($ids_format)";
92 - }
93 -
94 - // Title
95 - if ( ! empty( $filter->post_title ) ) {
96 - $filter->where[] = $this->wpdb->prepare( "AND $ca.post_title LIKE %s", '%' . $filter->post_title . '%' );
97 - }
98 -
99 - // Name(slug)
100 - if ( ! empty( $filter->post_name ) ) {
101 - $filter->where[] = $this->wpdb->prepare( "AND $ca.post_name = %s", $filter->post_name );
102 - }
103 -
104 - // Author
105 - if ( ! empty( $filter->post_author ) ) {
106 - $filter->where[] = $this->wpdb->prepare( "AND $ca.post_author = %d", $filter->post_author );
107 - }
108 -
109 - // Authors
110 - if ( ! empty( $filter->post_authors ) ) {
111 - $post_authors_format = LP_Helper::db_format_array( $filter->post_authors, '%d' );
112 - $filter->where[] = $this->wpdb->prepare( "AND $ca.post_author IN (" . $post_authors_format . ')', $filter->post_authors );
113 - }
114 -
115 - /**
116 - * Type price
117 - *
118 - * if 'free' and 'paid' are not in the array or not null, we will filter the price
119 - */
120 - if ( ! empty( $filter->type_price ) &&
121 - ( ! in_array( 'free', $filter->type_price ) && ! in_array( 'paid', $filter->type_price ) ) ) {
122 - foreach ( $filter->type_price as $type_price ) {
123 - switch ( $type_price ) {
124 - case 'free':
125 - $filter->where[] = 'AND price_to_sort = 0';
126 - break;
127 - case 'paid':
128 - $filter->where[] = 'AND price_to_sort > 0';
129 - break;
130 - }
131 - }
132 - }
133 -
134 - // Is sale
135 - if ( ! empty( $filter->is_sale ) ) {
136 - $filter->where[] = 'AND is_sale = 1';
137 - }
138 -
139 - // Is feature
140 - if ( ! empty( $filter->is_feature ) ) {
141 - $filter = $this->get_courses_in_feature( $filter );
142 - }
143 -
144 - // Levels
145 - if ( ! empty( $filter->levels ) ) {
146 - $filter->join[] = "INNER JOIN $this->tb_postmeta AS pml ON c.ID = pml.post_id";
147 - $filter->where[] = $this->wpdb->prepare( 'AND pml.meta_key = %s', '_lp_level' );
148 - $levels_format = LP_Helper::db_format_array( $filter->levels, '%s' );
149 - $filter->where[] = $this->wpdb->prepare( 'AND pml.meta_value IN (' . $levels_format . ')', $filter->levels );
150 - }
151 -
152 - // Course type
153 - if ( ! empty( $filter->type ) && $filter->type !== 'all' ) {
154 - if ( $filter->type === 'offline' ) {
155 - $filter->join[] = "INNER JOIN $this->tb_postmeta AS pm_off ON c.ID = pm_off.post_id";
156 - $filter->where[] = $this->wpdb->prepare( 'AND pm_off.meta_key = %s', '_lp_offline_course' );
157 - $filter->where[] = $this->wpdb->prepare( 'AND pm_off.meta_value = %s', 'yes' );
158 - } else {
159 - $filter->where[] = $this->wpdb->prepare(
160 - "AND c.ID NOT IN
161 - ( SELECT id FROM $this->tb_posts as p1
162 - INNER JOIN $this->tb_postmeta as pm_ol on p1.ID = pm_ol.post_id
163 - WHERE pm_ol.meta_key = %s AND pm_ol.meta_value = %s )",
164 - '_lp_offline_course',
165 - 'yes'
166 - );
167 - }
168 - }
169 -
170 - $filter = apply_filters( 'lp/courses-json/query/filter', $filter );
171 -
172 - return $this->execute( $filter, $total_rows );
173 - }
174 -
175 - /**
176 - * Get list courses is on popular
177 - * Use "UNION" to merge 2 query
178 - *
179 - * @param CourseJsonFilter $filter
180 - *
181 - * @return CourseJsonFilter
182 - * @throws Exception
183 - * @version 1.0.9
184 - * @since 4.3.2.3
185 - */
186 - public function get_courses_order_by_popular( CourseJsonFilter &$filter ): CourseJsonFilter {
187 - // Set list name columns get
188 - //$columns_table_posts = $this->get_cols_of_table( $this->tb_posts );
189 - //$filter->fields = array_merge( $columns_table_posts, $filter->fields );
190 - $db = CourseJsonDB::getInstance();
191 -
192 - $filter_user_course = clone $filter;
193 - $filter_course_not_attend = clone $filter;
194 -
195 - // Query get users total attend courses
196 - $fields_user_course_require = [ 'c.ID', 'COUNT(c.ID) AS total' ];
197 - $filter_user_course->fields = array( 'c.ID', 'COUNT(c.ID) AS total' );
198 - if ( ! empty( $filter_user_course->only_fields ) ) {
199 - $pattern = '#ID.*#';
200 - foreach ( $filter_user_course->only_fields as $k => $field ) {
201 - if ( preg_match( $pattern, $field ) ) {
202 - unset( $filter_user_course->only_fields[ $k ] );
203 - }
204 - }
205 - $filter_user_course->only_fields = array_unique( array_merge( $filter_user_course->only_fields, $fields_user_course_require ) );
206 - }
207 -
208 - $filter_user_course->join[] = "INNER JOIN {$this->tb_lp_user_items} AS ui ON c.ID = ui.item_id";
209 - $filter_user_course->where[] = $this->wpdb->prepare( 'AND ui.item_type = %s', LP_COURSE_CPT );
210 - $filter_user_course->where[] = $this->wpdb->prepare(
211 - 'AND (status = %s OR status = %s OR status = %s)',
212 - LP_COURSE_ENROLLED,
213 - LP_COURSE_PURCHASED,
214 - LP_COURSE_FINISHED
215 - );
216 - $filter_user_course->group_by = 'c.ID';
217 - $filter_user_course->order_by = '';
218 - $filter_user_course->return_string_query = true;
219 -
220 - $query_user_course = $db->get_courses( $filter_user_course );
221 -
222 - // Query get courses not attend
223 - $filter_user_course_cl = clone $filter_user_course;
224 - $filter_user_course_cl->only_fields = array( 'c.ID' );
225 - $query_user_course_for_not_in = $db->get_courses( $filter_user_course_cl );
226 -
227 - $fields_user_course_not_attend_require = [ 'c.ID', '0 AS total' ];
228 - $filter_course_not_attend->fields = [ 'c.ID', '0 AS total' ];
229 - if ( ! empty( $filter_course_not_attend->only_fields ) ) {
230 - $pattern = '#ID.*#';
231 - foreach ( $filter_course_not_attend->only_fields as $k => $field ) {
232 - if ( preg_match( $pattern, $field ) ) {
233 - unset( $filter_course_not_attend->only_fields[ $k ] );
234 - }
235 - }
236 - $filter_course_not_attend->only_fields = array_unique( array_merge( $filter_course_not_attend->only_fields, $fields_user_course_not_attend_require ) );
237 - }
238 - $filter_course_not_attend->where[] = 'AND c.ID NOT IN(' . $query_user_course_for_not_in . ')';
239 -
240 - $filter_course_not_attend->order_by = '';
241 - $filter_course_not_attend->return_string_query = true;
242 -
243 - $query_course_not_attend = $db->get_courses( $filter_course_not_attend );
244 -
245 - $filter->union[] = $query_user_course;
246 - $filter->union[] = $query_course_not_attend;
247 - $filter->order_by = 'total';
248 - $filter->order = 'DESC';
249 -
250 - return $filter;
251 - }
252 -
253 - /**
254 - * Get list courses is on feature
255 - *
256 - * @param CourseJsonFilter $filter
257 - *
258 - * @return CourseJsonFilter
259 - * @author tungnx
260 - * @version 1.0.0
261 - * @since 4.1.5
262 - */
263 - public function get_courses_in_feature( CourseJsonFilter &$filter ): CourseJsonFilter {
264 - $filter->join[] = "INNER JOIN $this->tb_postmeta AS pmf ON c.ID = pmf.post_id";
265 - $filter->where[] = $this->wpdb->prepare( 'AND pmf.meta_key = %s', '_lp_featured' );
266 - $filter->where[] = $this->wpdb->prepare( 'AND pmf.meta_value = %s', 'yes' );
267 -
268 - return $filter;
269 - }
270 -
271 - /**
272 - * Get total courses of Author
273 - *
274 - * @param int $author_id
275 - * @param array $status
276 - *
277 - * @return CourseJsonFilter
278 - * @since 4.3.4 Clone from LP_Course_DB::count_courses_of_author
279 - * @version 1.0.0
280 - */
281 - public function count_courses_of_author( int $author_id, array $status = [] ): CourseJsonFilter {
282 - $filter = new CourseJsonFilter();
283 - $filter->only_fields = array( 'ID' );
284 - $filter->post_author = $author_id;
285 - $filter->post_status = $status;
286 - if ( empty( $status ) ) {
287 - $filter->post_status = [];
288 - }
289 - $filter->field_count = 'ID';
290 - $filter->query_count = true;
291 -
292 - return apply_filters( 'lp/user/course/query/filter/count-courses-of-author', $filter );
293 - }
294 -}
1 +<?php
2 +
3 +namespace LearnPress\Databases\Course;
4 +
5 +use Exception;
6 +use LearnPress\Databases\DataBase;
7 +use LearnPress\Filters\Course\CourseJsonFilter;
8 +use LP_Helper;
9 +
10 +defined( 'ABSPATH' ) || exit();
11 +
12 +/**
13 + * Class CourseJsonDB
14 + *
15 + * Move from LP_Course_JSON_DB to here
16 + *
17 + * @since 4.3.2.3
18 + * @version 1.0.1
19 + */
20 +class CourseJsonDB extends DataBase {
21 + private static $_instance;
22 +
23 + protected function __construct() {
24 + parent::__construct();
25 + }
26 +
27 + public static function getInstance() {
28 + if ( is_null( self::$_instance ) ) {
29 + self::$_instance = new self();
30 + }
31 +
32 + return self::$_instance;
33 + }
34 +
35 + /**
36 + * Get Courses
37 + *
38 + * @param CourseJsonFilter $filter
39 + * @param int $total_rows return total_rows
40 + *
41 + * @return array|int|string|null
42 + * @throws Exception
43 + * @version 1.0.1
44 + * @since 4.2.6.9
45 + */
46 + public function get_courses( CourseJsonFilter $filter, int &$total_rows = 0 ) {
47 + $filter->fields = array_merge( $filter->all_fields, $filter->fields );
48 +
49 + if ( empty( $filter->collection ) ) {
50 + $filter->collection = $this->tb_lp_courses;
51 + }
52 +
53 + if ( empty( $filter->collection_alias ) ) {
54 + $filter->collection_alias = 'c';
55 + }
56 +
57 + $ca = $filter->collection_alias;
58 +
59 + // Find ID
60 + if ( ! empty( $filter->ID ) ) {
61 + $filter->where[] = $this->wpdb->prepare( "AND $ca.ID = %d", $filter->ID );
62 + }
63 +
64 + // Status
65 + $filter->post_status = (array) $filter->post_status;
66 + if ( ! empty( $filter->post_status ) ) {
67 + $post_status_format = LP_Helper::db_format_array( $filter->post_status, '%s' );
68 + $filter->where[] = $this->wpdb->prepare( "AND $ca.post_status IN (" . $post_status_format . ')', $filter->post_status );
69 + }
70 +
71 + // Exclude status auto-draft, because Admin of WP not show auto-draft in list post, so all front-end and back-end of LP also not show auto-draft
72 + if ( ! in_array( 'auto-draft', $filter->post_status, true ) ) {
73 + $filter->where[] = $this->wpdb->prepare( "AND $ca.post_status != %s", 'auto-draft' );
74 + }
75 +
76 + // Term ids
77 + if ( ! empty( $filter->term_ids ) ) {
78 + // Sanitize term ids
79 + $filter->term_ids = array_map( 'absint', $filter->term_ids );
80 + $term_ids_format = join( ',', $filter->term_ids );
81 + $filter->join[] = "INNER JOIN $this->tb_term_relationships AS r_term_p ON $ca.ID = r_term_p.object_id";
82 + $filter->join[] = "INNER JOIN $this->tb_term_taxonomy AS tx_p ON r_term_p.term_taxonomy_id = tx_p.term_taxonomy_id";
83 + $filter->where[] = "AND r_term_p.term_taxonomy_id IN ($term_ids_format)";
84 + $filter->where[] = $this->wpdb->prepare( 'AND tx_p.taxonomy = %s', $filter->taxonomy );
85 + }
86 +
87 + // Course ids
88 + if ( ! empty( $filter->ids ) ) {
89 + $ids = array_map( 'absint', $filter->ids );
90 + $ids_format = join( ',', $ids );
91 + $filter->where[] = "AND $ca.ID IN ($ids_format)";
92 + }
93 +
94 + // Title
95 + if ( ! empty( $filter->post_title ) ) {
96 + $filter->where[] = $this->wpdb->prepare( "AND $ca.post_title LIKE %s", '%' . $filter->post_title . '%' );
97 + }
98 +
99 + // Name(slug)
100 + if ( ! empty( $filter->post_name ) ) {
101 + $filter->where[] = $this->wpdb->prepare( "AND $ca.post_name = %s", $filter->post_name );
102 + }
103 +
104 + // Author
105 + if ( ! empty( $filter->post_author ) ) {
106 + $filter->where[] = $this->wpdb->prepare( "AND $ca.post_author = %d", $filter->post_author );
107 + }
108 +
109 + // Authors
110 + if ( ! empty( $filter->post_authors ) ) {
111 + $post_authors_format = LP_Helper::db_format_array( $filter->post_authors, '%d' );
112 + $filter->where[] = $this->wpdb->prepare( "AND $ca.post_author IN (" . $post_authors_format . ')', $filter->post_authors );
113 + }
114 +
115 + /**
116 + * Type price
117 + *
118 + * if 'free' and 'paid' are not in the array or not null, we will filter the price
119 + */
120 + if ( ! empty( $filter->type_price ) &&
121 + ( ! in_array( 'free', $filter->type_price ) && ! in_array( 'paid', $filter->type_price ) ) ) {
122 + foreach ( $filter->type_price as $type_price ) {
123 + switch ( $type_price ) {
124 + case 'free':
125 + $filter->where[] = 'AND price_to_sort = 0';
126 + break;
127 + case 'paid':
128 + $filter->where[] = 'AND price_to_sort > 0';
129 + break;
130 + }
131 + }
132 + }
133 +
134 + // Is sale
135 + if ( ! empty( $filter->is_sale ) ) {
136 + $filter->where[] = 'AND is_sale = 1';
137 + }
138 +
139 + // Is feature
140 + if ( ! empty( $filter->is_feature ) ) {
141 + $filter = $this->get_courses_in_feature( $filter );
142 + }
143 +
144 + // Levels
145 + if ( ! empty( $filter->levels ) ) {
146 + $filter->join[] = "INNER JOIN $this->tb_postmeta AS pml ON c.ID = pml.post_id";
147 + $filter->where[] = $this->wpdb->prepare( 'AND pml.meta_key = %s', '_lp_level' );
148 + $levels_format = LP_Helper::db_format_array( $filter->levels, '%s' );
149 + $filter->where[] = $this->wpdb->prepare( 'AND pml.meta_value IN (' . $levels_format . ')', $filter->levels );
150 + }
151 +
152 + // Course type
153 + if ( ! empty( $filter->type ) && $filter->type !== 'all' ) {
154 + if ( $filter->type === 'offline' ) {
155 + $filter->join[] = "INNER JOIN $this->tb_postmeta AS pm_off ON c.ID = pm_off.post_id";
156 + $filter->where[] = $this->wpdb->prepare( 'AND pm_off.meta_key = %s', '_lp_offline_course' );
157 + $filter->where[] = $this->wpdb->prepare( 'AND pm_off.meta_value = %s', 'yes' );
158 + } else {
159 + $filter->where[] = $this->wpdb->prepare(
160 + "AND c.ID NOT IN
161 + ( SELECT id FROM $this->tb_posts as p1
162 + INNER JOIN $this->tb_postmeta as pm_ol on p1.ID = pm_ol.post_id
163 + WHERE pm_ol.meta_key = %s AND pm_ol.meta_value = %s )",
164 + '_lp_offline_course',
165 + 'yes'
166 + );
167 + }
168 + }
169 +
170 + $filter = apply_filters( 'lp/courses-json/query/filter', $filter );
171 +
172 + return $this->execute( $filter, $total_rows );
173 + }
174 +
175 + /**
176 + * Get list courses is on popular
177 + * Use "UNION" to merge 2 query
178 + *
179 + * @param CourseJsonFilter $filter
180 + *
181 + * @return CourseJsonFilter
182 + * @throws Exception
183 + * @version 1.0.9
184 + * @since 4.3.2.3
185 + */
186 + public function get_courses_order_by_popular( CourseJsonFilter &$filter ): CourseJsonFilter {
187 + // Set list name columns get
188 + //$columns_table_posts = $this->get_cols_of_table( $this->tb_posts );
189 + //$filter->fields = array_merge( $columns_table_posts, $filter->fields );
190 + $db = CourseJsonDB::getInstance();
191 +
192 + $filter_user_course = clone $filter;
193 + $filter_course_not_attend = clone $filter;
194 +
195 + // Query get users total attend courses
196 + $fields_user_course_require = [ 'c.ID', 'COUNT(c.ID) AS total' ];
197 + $filter_user_course->fields = array( 'c.ID', 'COUNT(c.ID) AS total' );
198 + if ( ! empty( $filter_user_course->only_fields ) ) {
199 + $pattern = '#ID.*#';
200 + foreach ( $filter_user_course->only_fields as $k => $field ) {
201 + if ( preg_match( $pattern, $field ) ) {
202 + unset( $filter_user_course->only_fields[ $k ] );
203 + }
204 + }
205 + $filter_user_course->only_fields = array_unique( array_merge( $filter_user_course->only_fields, $fields_user_course_require ) );
206 + }
207 +
208 + $filter_user_course->join[] = "INNER JOIN {$this->tb_lp_user_items} AS ui ON c.ID = ui.item_id";
209 + $filter_user_course->where[] = $this->wpdb->prepare( 'AND ui.item_type = %s', LP_COURSE_CPT );
210 + $filter_user_course->where[] = $this->wpdb->prepare(
211 + 'AND (status = %s OR status = %s OR status = %s)',
212 + LP_COURSE_ENROLLED,
213 + LP_COURSE_PURCHASED,
214 + LP_COURSE_FINISHED
215 + );
216 + $filter_user_course->group_by = 'c.ID';
217 + $filter_user_course->order_by = '';
218 + $filter_user_course->return_string_query = true;
219 +
220 + $query_user_course = $db->get_courses( $filter_user_course );
221 +
222 + // Query get courses not attend
223 + $filter_user_course_cl = clone $filter_user_course;
224 + $filter_user_course_cl->only_fields = array( 'c.ID' );
225 + $query_user_course_for_not_in = $db->get_courses( $filter_user_course_cl );
226 +
227 + $fields_user_course_not_attend_require = [ 'c.ID', '0 AS total' ];
228 + $filter_course_not_attend->fields = [ 'c.ID', '0 AS total' ];
229 + if ( ! empty( $filter_course_not_attend->only_fields ) ) {
230 + $pattern = '#ID.*#';
231 + foreach ( $filter_course_not_attend->only_fields as $k => $field ) {
232 + if ( preg_match( $pattern, $field ) ) {
233 + unset( $filter_course_not_attend->only_fields[ $k ] );
234 + }
235 + }
236 + $filter_course_not_attend->only_fields = array_unique( array_merge( $filter_course_not_attend->only_fields, $fields_user_course_not_attend_require ) );
237 + }
238 + $filter_course_not_attend->where[] = 'AND c.ID NOT IN(' . $query_user_course_for_not_in . ')';
239 +
240 + $filter_course_not_attend->order_by = '';
241 + $filter_course_not_attend->return_string_query = true;
242 +
243 + $query_course_not_attend = $db->get_courses( $filter_course_not_attend );
244 +
245 + $filter->union[] = $query_user_course;
246 + $filter->union[] = $query_course_not_attend;
247 + $filter->order_by = 'total';
248 + $filter->order = 'DESC';
249 +
250 + return $filter;
251 + }
252 +
253 + /**
254 + * Get list courses is on feature
255 + *
256 + * @param CourseJsonFilter $filter
257 + *
258 + * @return CourseJsonFilter
259 + * @author tungnx
260 + * @version 1.0.0
261 + * @since 4.1.5
262 + */
263 + public function get_courses_in_feature( CourseJsonFilter &$filter ): CourseJsonFilter {
264 + $filter->join[] = "INNER JOIN $this->tb_postmeta AS pmf ON c.ID = pmf.post_id";
265 + $filter->where[] = $this->wpdb->prepare( 'AND pmf.meta_key = %s', '_lp_featured' );
266 + $filter->where[] = $this->wpdb->prepare( 'AND pmf.meta_value = %s', 'yes' );
267 +
268 + return $filter;
269 + }
270 +
271 + /**
272 + * Get total courses of Author
273 + *
274 + * @param int $author_id
275 + * @param array $status
276 + *
277 + * @return CourseJsonFilter
278 + * @since 4.3.4 Clone from LP_Course_DB::count_courses_of_author
279 + * @version 1.0.0
280 + */
281 + public function count_courses_of_author( int $author_id, array $status = [] ): CourseJsonFilter {
282 + $filter = new CourseJsonFilter();
283 + $filter->only_fields = array( 'ID' );
284 + $filter->post_author = $author_id;
285 + $filter->post_status = $status;
286 + if ( empty( $status ) ) {
287 + $filter->post_status = [];
288 + }
289 + $filter->field_count = 'ID';
290 + $filter->query_count = true;
291 +
292 + return apply_filters( 'lp/user/course/query/filter/count-courses-of-author', $filter );
293 + }
294 +}