PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.7
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 4.2.1 All 138 releases
learnpress / inc / Services / CourseService.php

CourseService.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.7, at inc/Services/CourseService.php

378 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace LearnPress\Services;
4
5 use Exception;
6 use LearnPress\Databases\Course\CourseJsonDB;
7 use LearnPress\Filters\Course\CourseJsonFilter;
8 use LearnPress\Helpers\Singleton;
9 use LearnPress\Models\CourseModel;
10 use LearnPress\Models\CoursePostModel;
11 use LearnPress\Models\PostModel;
12 use LearnPress\Models\UserModel;
13 use LP_Debug;
14 use LP_Helper;
15 use LP_Settings;
16 use Throwable;
17
18 /**
19 * Class CourseService
20 *
21 * Create course with data.
22 *
23 * @package LearnPress\Services
24 * @since 4.3.0
25 * @version 1.0.1
26 */
27 class CourseService {
28 use Singleton;
29
30 public function init() {
31 }
32
33 /**
34 * Create course info main
35 * Data of columns posts
36 *
37 * meta_input for metadata
38 *
39 * @param array $data [ 'post_title' => '', 'post_content' => '', 'post_status' => '', 'post_author' => , 'meta_input' => [] ]
40 *
41 * @throws Exception
42 */
43 public function create_info_main( array $data ): CoursePostModel {
44 $coursePostModelNew = new CoursePostModel( $data );
45
46 // Set meta data
47 if ( isset( $data['meta_input'] ) ) {
48 $coursePostModelNew->meta_data = (object) $data['meta_input'];
49 }
50
51 $coursePostModelNew->save();
52
53 return $coursePostModelNew;
54 }
55
56 /**
57 * Update categories for course
58 * Create categories if not exists
59 *
60 * @param $course_id
61 * @param int[] $category_ids
62 *
63 * @return void
64 * @since 4.3.6
65 * @version 1.0.0
66 */
67 public function update_categories( $course_id, array $category_ids ) {
68 // Create categories if not exists
69 foreach ( $category_ids as $category_id ) {
70 $term_check = term_exists( $category_id, CoursePostModel::TAXONOMY_CATEGORY );
71 if ( ! $term_check ) {
72 wp_insert_term( $category_id, CoursePostModel::TAXONOMY_CATEGORY );
73 }
74 }
75
76 wp_set_post_terms( $course_id, $category_ids, CoursePostModel::TAXONOMY_CATEGORY );
77 }
78
79 /**
80 * Update tags for course
81 * Create tags if not exists
82 *
83 * @param $course_id
84 * @param array $tag_ids
85 *
86 * @return void
87 * @since 4.3.6
88 * @version 1.0.0
89 */
90 public function update_tags( $course_id, array $tag_ids ) {
91 // Create tags if not exists
92 foreach ( $tag_ids as $tag_id ) {
93 $term_check = term_exists( $tag_id, CoursePostModel::TAXONOMY_TAG );
94 if ( ! $term_check ) {
95 wp_insert_term( $tag_id, CoursePostModel::TAXONOMY_TAG );
96 }
97 }
98
99 wp_set_post_terms( $course_id, $tag_ids, CoursePostModel::TAXONOMY_TAG );
100 }
101
102 /**
103 * Duplicate course
104 *
105 * @throws Exception
106 * @since 4.3.6
107 * @version 1.0.0
108 */
109 public function duplicate( CourseModel $courseModel ): CourseModel {
110 $coursePostModel = new CoursePostModel( $courseModel );
111 $coursePostModel->get_all_metadata();
112 $coursePostModelNew = new CoursePostModel( $coursePostModel );
113 $coursePostModelNew->ID = null;
114 $coursePostModelNew->post_title = $coursePostModelNew->post_title . ' (Copy)';
115 $coursePostModelNew->save();
116
117 // Duplicate sections
118 $sections = $courseModel->get_section_items();
119 foreach ( $sections as $section ) {
120 $section_name = $section->section_name ?? $section->title ?? '';
121 $section_description = $section->section_description ?? $section->description ?? '';
122
123 $courseSectionModel = $coursePostModelNew->add_section(
124 [
125 'section_name' => $section_name,
126 'section_description' => $section_description,
127 ]
128 );
129
130 // Duplicate items for section
131 $items = $section->items ?? [];
132 foreach ( $items as $item ) {
133 $item_title = $item->title ?? '';
134 $item_type = $item->type ?? $item->item_type ?? '';
135 $item_content = '';
136
137 // Get item content from post
138 $item_post = get_post( $item->item_id ?? $item->id ?? 0 );
139 if ( $item_post ) {
140 $item_content = $item_post->post_content ?? '';
141 }
142
143 $courseSectionModel->create_item_and_add(
144 [
145 'item_title' => $item_title,
146 'item_type' => $item_type,
147 'item_content' => $item_content,
148 ]
149 );
150 }
151 }
152
153 return $courseModel;
154 }
155
156 /**
157 * Handle params before query list courses on table learnpress_courses
158 *
159 * @param CourseJsonFilter $filter
160 * @param array $param
161 *
162 * @return void
163 * @since 4.3.7
164 * @version 1.0.0
165 */
166 public static function handle_params_for_query_list_courses( CourseJsonFilter &$filter, array $param = [] ) {
167 $filter->page = absint( $param['paged'] ?? 1 );
168 $filter->post_title = LP_Helper::sanitize_params_submitted( trim( $param['c_search'] ?? '' ) );
169 $db = CourseJsonDB::getInstance();
170
171 // Get Columns
172 $fields_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_fields'] ?? '' ) );
173 if ( ! empty( $fields_str ) ) {
174 $fields = explode( ',', $fields_str );
175 foreach ( $fields as $key => $field ) {
176 $fields[ $key ] = $db->wpdb->prepare( '%i', $field );
177 }
178 $filter->fields = $fields;
179 }
180
181 // Get only columns
182 $fields_only_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_only_fields'] ?? '' ) );
183 if ( ! empty( $fields_only_str ) ) {
184 $fields_only = explode( ',', $fields_only_str );
185 foreach ( $fields_only as $key => $field ) {
186 $fields_only[ $key ] = $db->wpdb->prepare( '%i', $field );
187 }
188 $filter->only_fields = $fields_only;
189 }
190
191 // Exclude Columns
192 $fields_exclude_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_exclude_fields'] ?? '' ) );
193 if ( ! empty( $fields_exclude_str ) ) {
194 $fields_exclude = explode( ',', $fields_exclude_str );
195 $filter->exclude_fields = $fields_exclude;
196 }
197
198 // Find by ids
199 $course_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['ids'] ?? '' ) );
200 if ( ! empty( $course_ids_str ) ) {
201 $course_ids = explode( ',', $course_ids_str );
202 $filter->ids = $course_ids;
203 }
204
205 // Author
206 $c_author = LP_Helper::sanitize_params_submitted( $param['c_author'] ?? 0 );
207 if ( ! empty( $c_author ) ) {
208 $filter->post_author = $c_author;
209 }
210 $author_ids_str = LP_Helper::sanitize_params_submitted( $param['c_authors'] ?? '' );
211 if ( ! empty( $author_ids_str ) ) {
212 $author_ids = explode( ',', $author_ids_str );
213 $filter->post_authors = $author_ids;
214 }
215
216 // Find by status
217 $post_status = LP_Helper::sanitize_params_submitted( $param['c_status'] ?? '' );
218 if ( ! empty( $post_status ) ) {
219 if ( 'all' !== $post_status ) {
220 $filter->post_status = explode( ',', $post_status );
221 }
222
223 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
224 || ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
225 $filter->post_status = [ PostModel::STATUS_PUBLISH ];
226 }
227 }
228
229 // Type price
230 if ( ! empty( $param['c_type_price'] ) ) {
231 $filter->type_price = explode( ',', LP_Helper::sanitize_params_submitted( urldecode( $param['c_type_price'] ) ) );
232 }
233
234 // On sale
235 if ( isset( $param['on_sale'] ) ) {
236 $filter->is_sale = 1;
237 }
238
239 // On feature
240 if ( isset( $param['on_feature'] ) ) {
241 $filter->is_feature = 1;
242 }
243
244 // Sort by level
245 $levels_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_level'] ?? '' ) );
246 if ( ! empty( $levels_str ) ) {
247 $levels = explode( ',', $levels_str );
248 if ( in_array( 'all', $levels ) ) {
249 $levels[] = '';
250 }
251 $filter->levels = $levels;
252 }
253
254 // Sort by type (oline/offline)
255 $course_type = LP_Helper::sanitize_params_submitted( urldecode( $param['c_type'] ?? '' ) );
256 if ( ! empty( $course_type ) ) {
257 $course_type = explode( ',', $course_type );
258 if ( in_array( 'online', $course_type ) && in_array( 'offline', $course_type ) ) {
259 $filter->type = 'all';
260 } else {
261 $filter->type = $course_type[0];
262 }
263 }
264
265 // Check is in category page.
266 if ( ! empty( $param['page_term_id_current'] ) && empty( $param['term_id'] ) ) {
267 $filter->term_ids[] = $param['page_term_id_current'];
268 } // Check is in tag page.
269 elseif ( ! empty( $param['page_tag_id_current'] ) && empty( $param['tag_id'] ) ) {
270 $filter->tag_ids[] = $param['page_tag_id_current'];
271 }
272
273 // Find by category
274 $term_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['term_id'] ?? '' ) );
275 if ( ! empty( $term_ids_str ) ) {
276 $term_ids = explode( ',', $term_ids_str );
277 $filter->term_ids = array_merge( $filter->term_ids, $term_ids );
278 }
279
280 // Find by tag
281 $tag_ids_str = LP_Helper::sanitize_params_submitted( urldecode( $param['tag_id'] ?? '' ) );
282 if ( ! empty( $tag_ids_str ) ) {
283 $tag_ids = explode( ',', $tag_ids_str );
284 $filter->tag_ids = array_merge( $filter->tag_ids, $tag_ids );
285 }
286
287 // Order by
288 $order_by = LP_Helper::sanitize_params_submitted( $param['order_by'] ?? 'post_date_gmt', 'key' );
289 if ( $order_by === 'post_date' ) {
290 $order_by = 'post_date_gmt';
291 }
292 $filter->order_by = $order_by;
293 $filter->order = LP_Helper::sanitize_params_submitted( $param['order'] ?? 'DESC', 'key' );
294 $filter->limit = $param['limit'] ?? LP_Settings::get_option( 'archive_course_limit', 10 );
295
296 // For search suggest courses
297 if ( ! empty( $param['c_suggest'] ) ) {
298 $filter->only_fields = [ 'ID', 'post_title' ];
299 $filter->limit = apply_filters( 'learn-press/services/rest-api/courses/suggest-limit', 10 );
300 }
301
302 do_action( 'learn-press/services/courses/handle_params_for_query_list_courses', $filter, $param );
303 }
304
305 /**
306 * Get list courses on table learnpress_courses
307 *
308 * @param CourseJsonFilter $filter
309 * @param int $total_rows
310 *
311 * @return array
312 * @throws Exception
313 * @version 1.0.0
314 * @since 4.3.7
315 */
316 public static function get_list_courses( CourseJsonFilter $filter, int &$total_rows = 0 ): array {
317 $db = CourseJsonDB::getInstance();
318
319 try {
320 $is_order_by_popular = 'popular' === $filter->order_by;
321
322 // Order by
323 switch ( $filter->order_by ) {
324 case 'price':
325 case 'price_low':
326 if ( 'price_low' === $filter->order_by ) {
327 $filter->order = 'ASC';
328 } else {
329 $filter->order = 'DESC';
330 }
331
332 $filter->order_by = 'price_to_sort';
333 break;
334 case 'popular':
335 $filter = $db->get_courses_order_by_popular( $filter );
336 break;
337 case 'post_title':
338 $filter->order = 'ASC';
339 break;
340 case 'post_title_desc':
341 $filter->order_by = 'post_title';
342 $filter->order = 'DESC';
343 break;
344 case 'menu_order':
345 $filter->order_by = 'menu_order';
346 $filter->order = 'ASC';
347 break;
348 default:
349 $filter = apply_filters( 'lp/services/courses/filter/order_by/' . $filter->order_by, $filter );
350 break;
351 }
352
353 // Query get results
354 /**
355 * @var CourseJsonFilter $filter
356 */
357 $filter = apply_filters( 'lp/services/courses/filter', $filter );
358 $courses = $db->get_courses( $filter, $total_rows );
359 } catch ( Throwable $e ) {
360 $courses = [];
361 LP_Debug::error_log( $e );
362 }
363
364 return $courses;
365 }
366
367 /**
368 * Check item type is support of course
369 *
370 * @param string $item_type
371 * @return bool
372 */
373 public static function check_is_item_type_of_course( string $item_type ): bool {
374 $course_item_types = coursemodel::item_types_support();
375 return in_array( $item_type, $course_item_types );
376 }
377 }
378