PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.0.6
Tutor LMS – eLearning and online course solution v2.0.6
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 4 years ago Backend_Page_Trait.php 4 years ago Course.php 4 years ago Course_Filter.php 4 years ago Course_List.php 4 years ago Course_Settings_Tabs.php 4 years ago Course_Widget.php 4 years ago Custom_Validation.php 4 years ago Dashboard.php 4 years ago FormHandler.php 4 years ago Frontend.php 4 years ago Gutenberg.php 4 years ago Input.php 4 years ago Instructor.php 4 years ago Instructors_List.php 4 years ago Lesson.php 4 years ago Options_V2.php 4 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 4 years ago Theme_Compatibility.php 5 years ago Tools.php 4 years ago Tools_V2.php 4 years ago Tutor.php 4 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 4 years ago Video_Stream.php 4 years ago Withdraw.php 4 years ago Withdraw_Requests_List.php 4 years ago WooCommerce.php 4 years ago
Course_List.php
442 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 self::update_course_status( $status, $id );
282
283 wp_send_json_success();
284 exit;
285 }
286
287 /**
288 * Handle ajax request for deleting course
289 *
290 * @return json response
291 * @since v2.0.0
292 */
293 public static function tutor_course_delete() {
294 tutor_utils()->checking_nonce();
295 $id = sanitize_text_field( $_POST['id'] );
296 $announcements = get_posts(array('post_type'=>'tutor_announcements','post_parent'=>$id));
297 foreach ($announcements as $announcement) {
298 wp_delete_post( $announcement->ID, true );
299 }
300 $delete = self::delete_course( $id );
301
302
303 // $delete = Announcements::delete_announcements( $action, $bulk_ids )( $id );
304 return wp_send_json( $delete );
305 exit;
306 }
307
308 /**
309 * Execute bulk action for enrolment list ex: complete | cancel
310 *
311 * @param string $bulk_ids ids that need to update.
312 * @return bool
313 * @since v2.0.0
314 */
315 public static function delete_course( $bulk_ids ): bool {
316 global $wpdb;
317 $post_table = $wpdb->posts;
318 $bulk_ids = sanitize_text_field( $bulk_ids );
319 $delete = $wpdb->query(
320 $wpdb->prepare(
321 " DELETE FROM {$post_table}
322 WHERE ID IN ($bulk_ids)
323 AND 1 = %d
324 ",
325 1
326 )
327 );
328
329 // Delete course meta.
330 $delete ? self::permanently_delete_course_meta( $bulk_ids ) : 0;
331
332 return false === $delete ? false : true;
333 }
334
335 /**
336 * Update course status
337 *
338 * @param string $status for updating course status.
339 * @param string $bulk_ids comma separated ids.
340 * @return bool
341 * @since v2.0.0
342 */
343 public static function update_course_status( string $status, $bulk_ids ): bool {
344 global $wpdb;
345 $post_table = $wpdb->posts;
346 $status = sanitize_text_field( $status );
347 $bulk_ids = sanitize_text_field( $bulk_ids );
348
349 $update = $wpdb->query(
350 $wpdb->prepare(
351 "UPDATE {$post_table}
352 SET post_status = %s
353 WHERE ID IN ($bulk_ids)",
354 $status
355 )
356 );
357
358 return true;
359 }
360
361 /**
362 * Get course enrolment list with student info
363 *
364 * @param int $course_id int | required.
365 * @return array
366 * @since v2.0.0
367 */
368 public static function course_enrollments_with_student_details( int $course_id ) {
369 global $wpdb;
370 $course_id = sanitize_text_field( $course_id );
371 $course_completed = 0;
372 $course_inprogress = 0;
373
374 $enrollments = $wpdb->get_results(
375 $wpdb->prepare(
376 "SELECT enroll.ID AS enroll_id, enroll.post_author AS enroll_author, user.*, course.ID AS course_id
377 FROM {$wpdb->posts} AS enroll
378 LEFT JOIN {$wpdb->users} AS user ON user.ID = enroll.post_author
379 LEFT JOIN {$wpdb->posts} AS course ON course.ID = enroll.post_parent
380 WHERE enroll.post_type = %s
381 AND enroll.post_status = %s
382 AND enroll.post_parent = %d
383 ",
384 'tutor_enrolled',
385 'completed',
386 $course_id
387 )
388 );
389
390 foreach ( $enrollments as $enrollment ) {
391 $course_progress = tutor_utils()->get_course_completed_percent( $course_id, $enrollment->enroll_author );
392 if ( $course_progress == 100 ) {
393 $course_completed++;
394 } else {
395 $course_inprogress++;
396 }
397 }
398
399 return array(
400 'enrollments' => $enrollments,
401 'total_completed' => $course_completed,
402 'total_inprogress' => $course_inprogress,
403 'total_enrollments' => count( $enrollments ),
404 );
405 }
406
407 /**
408 * Delete post meta permanently
409 *
410 * @param string $bulk_ids | comma separated ids.
411 *
412 * @return bool
413 *
414 * @since v2.0.0
415 */
416 public static function permanently_delete_course_meta( $bulk_ids ): bool {
417 global $wpdb;
418 $wpdb->query(
419 $wpdb->prepare(
420 " DELETE FROM {$wpdb->postmeta}
421 WHERE post_id IN ($bulk_ids)
422 AND 1 = %d
423 ",
424 1
425 )
426 );
427 return true;
428 }
429
430 /**
431 * Check wheather course is public or not
432 *
433 * @param integer $course_id course id to check with.
434 *
435 * @return boolean true if public otherwise false.
436 */
437 public static function is_public( int $course_id ): bool {
438 $is_public = get_post_meta( $course_id, '_tutor_is_public_course', true );
439 return 'yes' === $is_public ? true : false;
440 }
441 }
442