PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / trunk
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses vtrunk
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 4.2.1 4.2.1.1 All 137 releases
learnpress / inc / Databases / Course / CourseJsonDB.php

CourseJsonDB.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses trunk, at inc/Databases/Course/CourseJsonDB.php

295 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 }
295