PluginProbe
Tutor LMS – eLearning and online course solution / 3.4.2
Tutor LMS – eLearning and online course solution v3.4.2
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 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 All 191 releases
← All changes | classes/Course_List.php +97 -73 trunk3.4.2 View file →
@@ -9,13 +9,14 @@
9 9 */
10 10
11 11 namespace TUTOR;
12 12
13 -defined( 'ABSPATH' ) || exit;
14 -
15 13 use Tutor\Helpers\QueryHelper;
16 14 use Tutor\Models\CourseModel;
17 15
16 +if ( ! defined( 'ABSPATH' ) ) {
17 + exit;
18 +}
18 19 /**
19 20 * Course List class
20 21 *
21 22 * @since 2.0.0
@@ -29,8 +30,15 @@
29 30
30 31 use Backend_Page_Trait;
31 32
32 33 /**
34 + * Page Title
35 + *
36 + * @var $page_title
37 + */
38 + public $page_title;
39 +
40 + /**
33 41 * Bulk Action
34 42 *
35 43 * @var $bulk_action
36 44 */
@@ -39,53 +47,37 @@
39 47 /**
40 48 * Constructor
41 49 *
42 50 * @return void
43 - *
44 51 * @since 2.0.0
45 52 */
46 53 public function __construct() {
54 + $this->page_title = __( 'Courses', 'tutor' );
47 55 /**
48 56 * Handle bulk action
49 57 *
50 - * @since 2.0.0
58 + * @since v2.0.0
51 59 */
52 60 add_action( 'wp_ajax_tutor_course_list_bulk_action', array( $this, 'course_list_bulk_action' ) );
53 61 /**
54 62 * Handle ajax request for updating course status
55 63 *
56 - * @since 2.0.0
64 + * @since v2.0.0
57 65 */
58 66 add_action( 'wp_ajax_tutor_change_course_status', array( $this, 'tutor_change_course_status' ) );
59 67 /**
60 68 * Handle ajax request for delete course
61 69 *
62 - * @since 2.0.0
70 + * @since v2.0.0
63 71 */
64 72 add_action( 'wp_ajax_tutor_course_delete', array( $this, 'tutor_course_delete' ) );
65 73 }
66 74
67 75 /**
68 - * Page title fallback
69 - *
70 - * @since 3.5.0
71 - *
72 - * @param string $name Property name.
73 - *
74 - * @return string
75 - */
76 - public function __get( $name ) {
77 - if ( 'page_title' === $name ) {
78 - return esc_html__( 'Courses', 'tutor' );
79 - }
80 - }
81 -
82 - /**
83 76 * Prepare bulk actions that will show on dropdown options
84 77 *
78 + * @return array
85 79 * @since 2.0.0
86 - *
87 - * @return array
88 80 */
89 81 public function prepare_bulk_actions(): array {
90 82 $actions = array(
91 83 $this->bulk_action_default(),
@@ -95,19 +87,24 @@
95 87 );
96 88
97 89 $active_tab = Input::get( 'data', '' );
98 90
99 - if ( CourseModel::STATUS_TRASH === $active_tab ) {
91 + if ( 'trash' === $active_tab ) {
100 92 array_push( $actions, $this->bulk_action_delete() );
101 93 }
102 - if ( CourseModel::STATUS_TRASH !== $active_tab ) {
94 + if ( 'trash' !== $active_tab ) {
103 95 array_push( $actions, $this->bulk_action_trash() );
104 96 }
105 97
106 - if ( ! User::is_admin() ) {
107 - $can_trash_post = tutor_utils()->get_option( 'instructor_can_delete_course' ) && current_user_can( 'edit_tutor_courses' );
98 + if ( ! current_user_can( 'administrator' ) ) {
99 + $can_trash_post = tutor_utils()->get_option( 'instructor_can_delete_course' ) && current_user_can( 'edit_tutor_course' );
108 100 if ( ! $can_trash_post ) {
109 - $actions = array_filter( $actions, fn ( $val ) => CourseModel::STATUS_TRASH !== $val['value'] );
101 + $actions = array_filter(
102 + $actions,
103 + function ( $val ) {
104 + return 'trash' !== $val['value'];
105 + }
106 + );
110 107 }
111 108 }
112 109 return apply_filters( 'tutor_course_bulk_actions', $actions );
113 110 }
@@ -114,10 +111,8 @@
114 111
115 112 /**
116 113 * Available tabs that will visible on the right side of page navbar
117 114 *
118 - * @since 2.0.0
119 - *
120 115 * @param string $category_slug category slug.
121 116 * @param integer $course_id course ID.
122 117 * @param string $date selected date | optional.
123 118 * @param string $search search by user name or email | optional.
@@ -122,8 +117,10 @@
122 117 * @param string $date selected date | optional.
123 118 * @param string $search search by user name or email | optional.
124 119 *
125 120 * @return array
121 + *
122 + * @since v2.0.0
126 123 */
127 124 public function tabs_key_value( $category_slug, $course_id, $date, $search ): array {
128 125 $url = apply_filters( 'tutor_data_tab_base_url', get_pagenum_link() );
129 126
@@ -137,9 +134,9 @@
137 134 $future = self::count_course( 'future', $category_slug, $course_id, $date, $search );
138 135
139 136 $tabs = array(
140 137 array(
141 - 'key' => '',
138 + 'key' => 'all',
142 139 'title' => __( 'All', 'tutor' ),
143 140 'value' => $all,
144 141 'url' => $url . '&data=all',
145 142 ),
@@ -195,10 +192,8 @@
195 192 /**
196 193 * Count courses by status & filters
197 194 * Count all | min | published | pending | draft
198 195 *
199 - * @since 2.0.0
200 - *
201 196 * @param string $status | required.
202 197 * @param string $category_slug course category | optional.
203 198 * @param string $course_id selected course id | optional.
204 199 * @param string $date selected date | optional.
@@ -204,8 +199,10 @@
204 199 * @param string $date selected date | optional.
205 200 * @param string $search_term search by user name or email | optional.
206 201 *
207 202 * @return int
203 + *
204 + * @since 2.0.0
208 205 */
209 206 protected static function count_course( string $status, $category_slug = '', $course_id = '', $date = '', $search_term = '' ): int {
210 207 $user_id = get_current_user_id();
211 208 $status = sanitize_text_field( $status );
@@ -230,11 +227,11 @@
230 227 }
231 228
232 229 $date_filter = sanitize_text_field( $date );
233 230
234 - $year = gmdate( 'Y', strtotime( $date_filter ) );
235 - $month = gmdate( 'm', strtotime( $date_filter ) );
236 - $day = gmdate( 'd', strtotime( $date_filter ) );
231 + $year = date( 'Y', strtotime( $date_filter ) );
232 + $month = date( 'm', strtotime( $date_filter ) );
233 + $day = date( 'd', strtotime( $date_filter ) );
237 234
238 235 // Add date query.
239 236 if ( '' !== $date_filter ) {
240 237 $args['date_query'] = array(
@@ -268,16 +265,16 @@
268 265
269 266 $the_query = self::course_list_query( $args, $user_id, $status );
270 267
271 268 return ! is_null( $the_query ) && isset( $the_query->found_posts ) ? $the_query->found_posts : $the_query;
269 +
272 270 }
273 271
274 272 /**
275 273 * Handle bulk action for enrollment cancel | delete
276 274 *
275 + * @return void
277 276 * @since 2.0.0
278 - *
279 - * @return void
280 277 */
281 278 public function course_list_bulk_action() {
282 279
283 280 tutor_utils()->checking_nonce();
@@ -285,31 +282,18 @@
285 282 $action = Input::post( 'bulk-action', '' );
286 283 $bulk_ids = Input::post( 'bulk-ids', '' );
287 284
288 285 // Check if user is privileged.
289 - if ( ! User::is_admin() ) {
290 - $course_ids = explode( ',', $bulk_ids );
291 -
292 - if ( current_user_can( 'edit_tutor_courses' ) ) {
286 + if ( ! current_user_can( 'administrator' ) ) {
287 + if ( current_user_can( 'edit_tutor_course' ) ) {
293 288 $can_publish_course = tutor_utils()->get_option( 'instructor_can_publish_course' );
294 289
295 - if ( CourseModel::STATUS_PUBLISH === $action && ! $can_publish_course ) {
290 + if ( 'publish' === $action && ! $can_publish_course ) {
296 291 wp_send_json_error( tutor_utils()->error_message() );
297 292 }
298 293 } else {
299 294 wp_send_json_error( tutor_utils()->error_message() );
300 295 }
301 -
302 - // Check if the course ids are instructors own course.
303 - $course_ids = array_filter(
304 - $course_ids,
305 - function ( $course_id ) {
306 - return tutor_utils()->is_instructor_of_this_course( get_current_user_id(), $course_id );
307 - }
308 - );
309 -
310 - $bulk_ids = implode( ',', $course_ids );
311 -
312 296 }
313 297
314 298 if ( '' === $action || '' === $bulk_ids ) {
315 299 wp_send_json_error( array( 'message' => __( 'Please select appropriate action', 'tutor' ) ) );
@@ -346,21 +330,20 @@
346 330
347 331 /**
348 332 * Handle ajax request for updating course status
349 333 *
334 + * @return void
350 335 * @since 2.0.0
351 - *
352 - * @return void
353 336 */
354 337 public static function tutor_change_course_status() {
355 338 tutor_utils()->checking_nonce();
356 339
357 340 $status = Input::post( 'status' );
358 - $id = Input::post( 'id', 0, Input::TYPE_INT );
341 + $id = Input::post( 'id' );
359 342 $course = get_post( $id );
360 343
361 344 // Check if user is privileged.
362 - if ( ! User::is_admin() ) {
345 + if ( ! current_user_can( 'administrator' ) ) {
363 346
364 347 if ( ! tutor_utils()->can_user_edit_course( get_current_user_id(), $course->ID ) ) {
365 348 wp_send_json_error( tutor_utils()->error_message() );
366 349 }
@@ -367,13 +350,13 @@
367 350
368 351 $can_delete_course = tutor_utils()->get_option( 'instructor_can_delete_course' );
369 352 $can_publish_course = tutor_utils()->get_option( 'instructor_can_publish_course' );
370 353
371 - if ( CourseModel::STATUS_PUBLISH === $status && ! $can_publish_course ) {
354 + if ( 'publish' === $status && ! $can_publish_course ) {
372 355 wp_send_json_error( tutor_utils()->error_message() );
373 356 }
374 357
375 - if ( CourseModel::STATUS_TRASH === $status && $can_delete_course ) {
358 + if ( 'trash' === $status && $can_delete_course ) {
376 359 $args = array(
377 360 'ID' => $id,
378 361 'post_status' => $status,
379 362 );
@@ -384,9 +367,9 @@
384 367 }
385 368 }
386 369 }
387 370
388 - if ( ! CourseModel::get_post_types( $course ) ) {
371 + if ( CourseModel::POST_TYPE !== $course->post_type ) {
389 372 wp_send_json_error( tutor_utils()->error_message() );
390 373 }
391 374
392 375 $args = array(
@@ -436,13 +419,11 @@
436 419
437 420 /**
438 421 * Execute bulk delete action
439 422 *
440 - * @since 2.0.0
441 - *
442 423 * @param string $bulk_ids ids that need to update.
443 - *
444 424 * @return bool
425 + * @since 2.0.0
445 426 */
446 427 public static function bulk_delete_course( $bulk_ids ): bool {
447 428 $bulk_ids = explode( ',', sanitize_text_field( $bulk_ids ) );
448 429
@@ -455,14 +436,14 @@
455 436
456 437 /**
457 438 * Update course status
458 439 *
459 - * @since 2.0.0
460 - *
461 440 * @param string $status for updating course status.
462 441 * @param string $bulk_ids comma separated ids.
463 442 *
464 443 * @return bool
444 + *
445 + * @since 2.0.0
465 446 */
466 447 public static function update_course_status( string $status, $bulk_ids ): bool {
467 448 global $wpdb;
468 449 $post_table = $wpdb->posts;
@@ -471,9 +452,9 @@
471 452
472 453 $ids = array_map( 'intval', explode( ',', $bulk_ids ) );
473 454 $in_clause = QueryHelper::prepare_in_clause( $ids );
474 455
475 - $wpdb->query(
456 + $update = $wpdb->query(
476 457 $wpdb->prepare(
477 458 "UPDATE {$post_table} SET post_status = %s WHERE ID IN ($in_clause)", //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
478 459 $status
479 460 )
@@ -482,15 +463,59 @@
482 463 return true;
483 464 }
484 465
485 466 /**
486 - * Check course is public or not
467 + * Get course enrollment list with student info
487 468 *
488 - * @since 1.0.0
469 + * @param int $course_id int | required.
470 + * @return array
471 + * @since 2.0.0
472 + */
473 + public static function course_enrollments_with_student_details( int $course_id ) {
474 + global $wpdb;
475 + $course_id = sanitize_text_field( $course_id );
476 + $course_completed = 0;
477 + $course_inprogress = 0;
478 +
479 + $enrollments = $wpdb->get_results(
480 + $wpdb->prepare(
481 + "SELECT enroll.ID AS enroll_id, enroll.post_author AS enroll_author, user.*, course.ID AS course_id
482 + FROM {$wpdb->posts} AS enroll
483 + LEFT JOIN {$wpdb->users} AS user ON user.ID = enroll.post_author
484 + LEFT JOIN {$wpdb->posts} AS course ON course.ID = enroll.post_parent
485 + WHERE enroll.post_type = %s
486 + AND enroll.post_status = %s
487 + AND enroll.post_parent = %d
488 + ",
489 + 'tutor_enrolled',
490 + 'completed',
491 + $course_id
492 + )
493 + );
494 +
495 + foreach ( $enrollments as $enrollment ) {
496 + $course_progress = tutor_utils()->get_course_completed_percent( $course_id, $enrollment->enroll_author );
497 + if ( 100 == $course_progress ) {
498 + $course_completed++;
499 + } else {
500 + $course_inprogress++;
501 + }
502 + }
503 +
504 + return array(
505 + 'enrollments' => $enrollments,
506 + 'total_completed' => $course_completed,
507 + 'total_inprogress' => $course_inprogress,
508 + 'total_enrollments' => count( $enrollments ),
509 + );
510 + }
511 +
512 + /**
513 + * Check wheather course is public or not
489 514 *
490 515 * @param integer $course_id course id to check with.
491 - *
492 516 * @return boolean true if public otherwise false.
517 + * @since 1.0.0
493 518 */
494 519 public static function is_public( int $course_id ): bool {
495 520 $is_public = get_post_meta( $course_id, '_tutor_is_public_course', true );
496 521 return 'yes' === $is_public ? true : false;
@@ -503,14 +528,13 @@
503 528 *
504 529 * @param array $args the query args.
505 530 * @param int $user_id the user id.
506 531 * @param string $status the post status.
507 - * @param bool $all_post_types should keep all post types.
508 532 *
509 533 * @return \WP_Query
510 534 */
511 - public static function course_list_query( $args, $user_id, $status, $all_post_types = false ) {
535 + public static function course_list_query( $args, $user_id, $status ) {
512 536
513 - $course_list_query = new \WP_Query( apply_filters( 'tutor_admin_course_list', $args, $user_id, $status, $all_post_types ) );
537 + $course_list_query = new \WP_Query( apply_filters( 'tutor_admin_course_list', $args, $user_id, $status ) );
514 538 return $course_list_query;
515 539 }
516 540 }