PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.0.8
Tutor LMS – eLearning and online course solution v2.0.8
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Course_List.php
tutor / classes Last commit date
Addons.php 4 years ago Admin.php 4 years ago Ajax.php 4 years ago Announcements.php 4 years ago Assets.php 3 years ago Backend_Page_Trait.php 4 years ago Course.php 3 years ago Course_Filter.php 4 years ago Course_List.php 3 years ago Course_Settings_Tabs.php 4 years ago Course_Widget.php 4 years ago Custom_Validation.php 4 years ago Dashboard.php 3 years ago FormHandler.php 4 years ago Frontend.php 3 years ago Gutenberg.php 4 years ago Input.php 3 years ago Instructor.php 4 years ago Instructors_List.php 3 years ago Lesson.php 4 years ago Options_V2.php 3 years ago Post_types.php 4 years ago Private_Course_Access.php 4 years ago Q_and_A.php 4 years ago Question_Answers_List.php 4 years ago Quiz.php 4 years ago Quiz_Attempts_List.php 4 years ago RestAPI.php 4 years ago Reviews.php 4 years ago Rewrite_Rules.php 4 years ago Shortcode.php 4 years ago Student.php 4 years ago Students_List.php 4 years ago Taxonomies.php 4 years ago Template.php 3 years ago Theme_Compatibility.php 5 years ago Tools.php 3 years ago Tools_V2.php 4 years ago Tutor.php 3 years ago TutorEDD.php 4 years ago Tutor_Base.php 5 years ago Tutor_List_Table.php 4 years ago Tutor_Setup.php 4 years ago Upgrader.php 4 years ago User.php 4 years ago Utils.php 3 years ago Video_Stream.php 4 years ago Withdraw.php 3 years ago Withdraw_Requests_List.php 4 years ago WooCommerce.php 3 years ago
Course_List.php
446 lines
1 <?php
2 /**
3 * Course List class
4 *
5 * @package Course List
6 * @since v2.0.0
7 */
8
9 namespace TUTOR;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14 /**
15 * Announcements class for handling logics
16 */
17 class Course_List {
18 /**
19 * Trait for utilities
20 *
21 * @var $page_title
22 */
23
24 use Backend_Page_Trait;
25 /**
26 * Page Title
27 *
28 * @var $page_title
29 */
30 public $page_title;
31
32 /**
33 * Bulk Action
34 *
35 * @var $bulk_action
36 */
37 public $bulk_action = true;
38
39 /**
40 * Handle dependencies
41 */
42 public function __construct() {
43 $this->page_title = __( 'Courses', 'tutor' );
44 /**
45 * Handle bulk action
46 *
47 * @since v2.0.0
48 */
49 add_action( 'wp_ajax_tutor_course_list_bulk_action', array( $this, 'course_list_bulk_action' ) );
50 /**
51 * Handle ajax request for updating course status
52 *
53 * @since v2.0.0
54 */
55 add_action( 'wp_ajax_tutor_change_course_status', array( __CLASS__, 'tutor_change_course_status' ) );
56 /**
57 * Handle ajax request for delete course
58 *
59 * @since v2.0.0
60 */
61 add_action( 'wp_ajax_tutor_course_delete', array( __CLASS__, 'tutor_course_delete' ) );
62 }
63
64 /**
65 * Prepare bulk actions that will show on dropdown options
66 *
67 * @return array
68 * @since v2.0.0
69 */
70 public function prepare_bulk_actions(): array {
71 $actions = array(
72 $this->bulk_action_default(),
73 $this->bulk_action_publish(),
74 $this->bulk_action_pending(),
75 $this->bulk_action_draft(),
76 );
77 $active_tab = isset( $_GET['data'] ) ? $_GET['data'] : '';
78 if ( 'trash' === $active_tab ) {
79 array_push( $actions, $this->bulk_action_delete() );
80 }
81 if ( 'trash' !== $active_tab ) {
82 array_push( $actions, $this->bulk_action_trash() );
83 }
84 return apply_filters( 'tutor_course_bulk_actions', $actions );
85 }
86
87 /**
88 * Available tabs that will visible on the right side of page navbar
89 *
90 * @param string $category_slug
91 * @param string $date selected date | optional.
92 * @param string $search search by user name or email | optional.
93 * @return array
94 * @since v2.0.0
95 */
96 public function tabs_key_value( $category_slug, $course_id, $date, $search ): array {
97 $url = get_pagenum_link();
98
99 $all = self::count_course( 'all', $category_slug, $course_id, $date, $search );
100 $mine = self::count_course( 'mine', $category_slug, $course_id, $date, $search );
101 $published = self::count_course( 'publish', $category_slug, $course_id, $date, $search );
102 $draft = self::count_course( 'draft', $category_slug, $course_id, $date, $search );
103 $pending = self::count_course( 'pending', $category_slug, $course_id, $date, $search );
104 $trash = self::count_course( 'trash', $category_slug, $course_id, $date, $search );
105
106 $tabs = array(
107 array(
108 'key' => 'all',
109 'title' => __( 'All', 'tutor' ),
110 'value' => $all,
111 'url' => $url . '&data=all',
112 ),
113 array(
114 'key' => 'mine',
115 'title' => __( 'Mine', 'tutor' ),
116 'value' => $mine,
117 'url' => $url . '&data=mine',
118 ),
119 array(
120 'key' => 'published',
121 'title' => __( 'Published', 'tutor' ),
122 'value' => $published,
123 'url' => $url . '&data=published',
124 ),
125 array(
126 'key' => 'draft',
127 'title' => __( 'Draft', 'tutor' ),
128 'value' => $draft,
129 'url' => $url . '&data=draft',
130 ),
131 array(
132 'key' => 'pending',
133 'title' => __( 'Pending', 'tutor' ),
134 'value' => $pending,
135 'url' => $url . '&data=pending',
136 ),
137 array(
138 'key' => 'trash',
139 'title' => __( 'Trash', 'tutor' ),
140 'value' => $trash,
141 'url' => $url . '&data=trash',
142 ),
143 );
144 return apply_filters( 'tutor_course_tabs', $tabs );
145 }
146
147 /**
148 * Count courses by status & filters
149 * Count all | min | published | pending | draft
150 *
151 * @param string $status | required.
152 * @param string $category_slug course category | optional.
153 * @param string $course_id selected course id | optional.
154 * @param string $date selected date | optional.
155 * @param string $search_term search by user name or email | optional.
156 * @return int
157 * @since v2.0.0
158 */
159 protected static function count_course( string $status, $category_slug = '', $course_id = '', $date = '', $search_term = '' ): int {
160 $user_id = get_current_user_id();
161 $status = sanitize_text_field( $status );
162 $course_id = sanitize_text_field( $course_id );
163 $date = sanitize_text_field( $date );
164 $search_term = sanitize_text_field( $search_term );
165 $category_slug = sanitize_text_field( $category_slug );
166
167 $args = array(
168 'post_type' => tutor()->course_post_type,
169 );
170
171 if ( 'all' === $status || 'mine' === $status ) {
172 $args['post_status'] = array( 'publish', 'pending', 'draft', 'private' );
173 } else {
174 $args['post_status'] = array( $status );
175 }
176
177 // Author query.
178 if ( 'mine' === $status || ! current_user_can( 'administrator' ) ) {
179 $args['author'] = $user_id;
180 }
181
182 $date_filter = sanitize_text_field( $date );
183
184 $year = date( 'Y', strtotime( $date_filter ) );
185 $month = date( 'm', strtotime( $date_filter ) );
186 $day = date( 'd', strtotime( $date_filter ) );
187
188 // Add date query.
189 if ( '' !== $date_filter ) {
190 $args['date_query'] = array(
191 array(
192 'year' => $year,
193 'month' => $month,
194 'day' => $day,
195 ),
196 );
197 }
198
199 if ( '' !== $course_id ) {
200 $args['p'] = $course_id;
201 }
202
203 // Search filter.
204 if ( '' !== $search_term ) {
205 $args['s'] = $search_term;
206 }
207
208 // Category filter.
209 if ( '' !== $category_slug ) {
210 $args['tax_query'] = array(
211 array(
212 'taxonomy' => 'course-category',
213 'field' => 'slug',
214 'terms' => $category_slug,
215 ),
216 );
217 }
218
219 $the_query = new \WP_Query( $args );
220
221 return ! is_null( $the_query ) && isset( $the_query->found_posts ) ? $the_query->found_posts : $the_query;
222
223 }
224
225 /**
226 * Handle bulk action for enrolment cancel | delete
227 *
228 * @return string JSON response.
229 * @since v2.0.0
230 */
231 public function course_list_bulk_action() {
232 // check nonce.
233 tutor_utils()->checking_nonce();
234 $action = isset( $_POST['bulk-action'] ) ? sanitize_text_field( $_POST['bulk-action'] ) : '';
235 $bulk_ids = isset( $_POST['bulk-ids'] ) ? sanitize_text_field( $_POST['bulk-ids'] ) : '';
236
237 if ( '' === $action || '' === $bulk_ids ) {
238 wp_send_json_error(array('message' => __('Please select appropriate action', 'tutor')));
239 exit;
240 }
241
242 if ( 'delete' === $action ) {
243 // Do action before delete.
244 do_action( 'before_tutor_course_bulk_action_delete', $bulk_ids );
245
246 $delete_courses = self::delete_course( $bulk_ids );
247
248 do_action( 'after_tutor_course_bulk_action_delete', $bulk_ids );
249 $delete_courses ? wp_send_json_success() : wp_send_json_error(array('message' => __('Could not delete selected courses', 'tutor')));
250 exit;
251 }
252
253 /**
254 * Do action before course update
255 *
256 * @param string $action (publish | pending | draft | trash).
257 * @param array $bulk_ids, course id.
258 */
259 do_action( 'before_tutor_course_bulk_action_update', $action, $bulk_ids );
260
261 $update_status = self::update_course_status( $action, $bulk_ids );
262
263 do_action( 'after_tutor_course_bulk_action_update', $action, $bulk_ids );
264
265 $update_status ? wp_send_json_success() : wp_send_json_error(array('message' => 'Could not update course status', 'tutor'));
266
267 exit;
268 }
269
270 /**
271 * Handle ajax request for updating course status
272 *
273 * @return json response
274 * @since v2.0.0
275 */
276 public static function tutor_change_course_status() {
277 tutor_utils()->checking_nonce();
278 $status = sanitize_text_field( $_POST['status'] );
279 $id = sanitize_text_field( $_POST['id'] );
280
281 $args = array(
282 'ID' => $id,
283 'post_status' => $status
284 );
285 wp_update_post( $args );
286
287 wp_send_json_success();
288 exit;
289 }
290
291 /**
292 * Handle ajax request for deleting course
293 *
294 * @return json response
295 * @since v2.0.0
296 */
297 public static function tutor_course_delete() {
298 tutor_utils()->checking_nonce();
299 $id = sanitize_text_field( $_POST['id'] );
300 $announcements = get_posts(array('post_type'=>'tutor_announcements','post_parent'=>$id));
301 foreach ($announcements as $announcement) {
302 wp_delete_post( $announcement->ID, true );
303 }
304 $delete = self::delete_course( $id );
305
306
307 // $delete = Announcements::delete_announcements( $action, $bulk_ids )( $id );
308 return wp_send_json( $delete );
309 exit;
310 }
311
312 /**
313 * Execute bulk action for enrolment list ex: complete | cancel
314 *
315 * @param string $bulk_ids ids that need to update.
316 * @return bool
317 * @since v2.0.0
318 */
319 public static function delete_course( $bulk_ids ): bool {
320 global $wpdb;
321 $post_table = $wpdb->posts;
322 $bulk_ids = sanitize_text_field( $bulk_ids );
323 $delete = $wpdb->query(
324 $wpdb->prepare(
325 " DELETE FROM {$post_table}
326 WHERE ID IN ($bulk_ids)
327 AND 1 = %d
328 ",
329 1
330 )
331 );
332
333 // Delete course meta.
334 $delete ? self::permanently_delete_course_meta( $bulk_ids ) : 0;
335
336 return false === $delete ? false : true;
337 }
338
339 /**
340 * Update course status
341 *
342 * @param string $status for updating course status.
343 * @param string $bulk_ids comma separated ids.
344 * @return bool
345 * @since v2.0.0
346 */
347 public static function update_course_status( string $status, $bulk_ids ): bool {
348 global $wpdb;
349 $post_table = $wpdb->posts;
350 $status = sanitize_text_field( $status );
351 $bulk_ids = sanitize_text_field( $bulk_ids );
352
353 $update = $wpdb->query(
354 $wpdb->prepare(
355 "UPDATE {$post_table}
356 SET post_status = %s
357 WHERE ID IN ($bulk_ids)",
358 $status
359 )
360 );
361
362 return true;
363 }
364
365 /**
366 * Get course enrolment list with student info
367 *
368 * @param int $course_id int | required.
369 * @return array
370 * @since v2.0.0
371 */
372 public static function course_enrollments_with_student_details( int $course_id ) {
373 global $wpdb;
374 $course_id = sanitize_text_field( $course_id );
375 $course_completed = 0;
376 $course_inprogress = 0;
377
378 $enrollments = $wpdb->get_results(
379 $wpdb->prepare(
380 "SELECT enroll.ID AS enroll_id, enroll.post_author AS enroll_author, user.*, course.ID AS course_id
381 FROM {$wpdb->posts} AS enroll
382 LEFT JOIN {$wpdb->users} AS user ON user.ID = enroll.post_author
383 LEFT JOIN {$wpdb->posts} AS course ON course.ID = enroll.post_parent
384 WHERE enroll.post_type = %s
385 AND enroll.post_status = %s
386 AND enroll.post_parent = %d
387 ",
388 'tutor_enrolled',
389 'completed',
390 $course_id
391 )
392 );
393
394 foreach ( $enrollments as $enrollment ) {
395 $course_progress = tutor_utils()->get_course_completed_percent( $course_id, $enrollment->enroll_author );
396 if ( $course_progress == 100 ) {
397 $course_completed++;
398 } else {
399 $course_inprogress++;
400 }
401 }
402
403 return array(
404 'enrollments' => $enrollments,
405 'total_completed' => $course_completed,
406 'total_inprogress' => $course_inprogress,
407 'total_enrollments' => count( $enrollments ),
408 );
409 }
410
411 /**
412 * Delete post meta permanently
413 *
414 * @param string $bulk_ids | comma separated ids.
415 *
416 * @return bool
417 *
418 * @since v2.0.0
419 */
420 public static function permanently_delete_course_meta( $bulk_ids ): bool {
421 global $wpdb;
422 $wpdb->query(
423 $wpdb->prepare(
424 " DELETE FROM {$wpdb->postmeta}
425 WHERE post_id IN ($bulk_ids)
426 AND 1 = %d
427 ",
428 1
429 )
430 );
431 return true;
432 }
433
434 /**
435 * Check wheather course is public or not
436 *
437 * @param integer $course_id course id to check with.
438 *
439 * @return boolean true if public otherwise false.
440 */
441 public static function is_public( int $course_id ): bool {
442 $is_public = get_post_meta( $course_id, '_tutor_is_public_course', true );
443 return 'yes' === $is_public ? true : false;
444 }
445 }
446