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 / Instructors_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
Instructors_List.php
432 lines
1 <?php
2 /**
3 * Instructor List
4 *
5 * @package Instructor List
6 */
7
8 namespace TUTOR;
9
10 use TUTOR\Students_List;
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 use TUTOR\Backend_Page_Trait;
17
18 class Instructors_List {
19
20 const INSTRUCTOR_LIST_PAGE = 'tutor-instructors';
21
22 /**
23 * Trait for utilities
24 *
25 * @var $page_title
26 */
27
28 use Backend_Page_Trait;
29 /**
30 * Page Title
31 *
32 * @var $page_title
33 */
34 public $page_title;
35
36 /**
37 * Bulk Action
38 *
39 * @var $bulk_action
40 */
41 public $bulk_action = true;
42
43 /**
44 * Handle dependencies
45 */
46 public function __construct() {
47 $this->page_title = __( 'Instructor', 'tutor' );
48 /**
49 * Handle bulk action
50 *
51 * @since v2.0.0
52 */
53 add_action( 'wp_ajax_tutor_instructor_bulk_action', array( $this, 'instructor_bulk_action' ) );
54 }
55
56 /**
57 * Available tabs that will visible on the right side of page navbar
58 *
59 * @param string $search, instructor search | optional.
60 * @param string $course_id, course id that belong to instructor | optional.
61 * @param string $date, user registered date | optional.
62 * @return array
63 * @since v2.0.0
64 */
65 public function tabs_key_value( $search = '', $course_id = '', $date = '' ): array {
66 $url = get_pagenum_link();
67 $approve = tutor_utils()->get_total_instructors( $search, array( 'approved' ), $course_id, $date );
68 $pending = tutor_utils()->get_total_instructors( $search, array( 'pending' ), $course_id, $date );
69 $blocked = tutor_utils()->get_total_instructors( $search, array( 'blocked' ), $course_id, $date );
70 $tabs = array(
71 array(
72 'key' => 'all',
73 'title' => __( 'All', 'tutor' ),
74 'value' => $approve + $pending + $blocked,
75 'url' => $url . '&data=all',
76 ),
77 array(
78 'key' => 'approved',
79 'title' => __( 'Approve', 'tutor' ),
80 'value' => $approve,
81 'url' => $url . '&data=approved',
82 ),
83 array(
84 'key' => 'pending',
85 'title' => __( 'Pending', 'tutor' ),
86 'value' => $pending,
87 'url' => $url . '&data=pending',
88 ),
89 array(
90 'key' => 'blocked',
91 'title' => __( 'Block', 'tutor' ),
92 'value' => $blocked,
93 'url' => $url . '&data=blocked',
94 ),
95 );
96 return $tabs;
97 }
98
99 /**
100 * Prepare bulk actions that will show on dropdown options
101 *
102 * @return array
103 * @since v2.0.0
104 */
105 public function prpare_bulk_actions(): array {
106 $actions = array(
107 $this->bulk_action_default(),
108 $this->bulk_action_approved(),
109 $this->bulk_action_pending(),
110 $this->bulk_action_blocked(),
111 );
112 return $actions;
113 }
114
115 /**
116 * Handle bulk action for instructor delete
117 *
118 * @return string JSON response.
119 * @since v2.0.0
120 */
121 public function instructor_bulk_action() {
122 // check nonce.
123 tutor_utils()->checking_nonce();
124 $action = isset( $_POST['bulk-action'] ) ? sanitize_text_field( $_POST['bulk-action'] ) : '';
125 $bulk_ids = isset( $_POST['bulk-ids'] ) ? sanitize_text_field( $_POST['bulk-ids'] ) : '';
126 isset( $_POST['bulkIds'] ) ? $bulk_ids = sanitize_text_field( $_POST['bulkIds'] ) : 0;
127
128 if ( '' === $action || '' === $bulk_ids ) {
129 return wp_send_json_error();
130 }
131 if ( 'delete' === $action ) {
132 // Delete user from student_list class.
133 do_action( 'tutor_before_instructor_delete', $bulk_ids );
134 $response = Students_List::delete_students( $bulk_ids );
135 do_action( 'tutor_after_instructor_delete', $bulk_ids );
136 } else {
137 do_action( 'tutor_before_instructor_update', $bulk_ids );
138 $response = self::update_instructors( $action, $bulk_ids );
139 do_action( 'tutor_after_instructor_delete', $bulk_ids );
140 }
141
142 $message = 'Instructor status updated';
143
144 return true === $response ? wp_send_json_success(array('status'=>$message)) : wp_send_json_error();
145 exit;
146 }
147
148 /**
149 * Execute bulk action for enrolment list ex: complete | cancel
150 *
151 * @param string $status hold status for updating.
152 * @param string $users_ids ids that need to update.
153 * @return bool
154 * @since v2.0.0
155 */
156 public static function update_instructors( $status, $user_ids ): bool {
157 global $wpdb;
158 $status = sanitize_text_field( $status );
159 $instructor_table = $wpdb->usermeta;
160 $update = $wpdb->query(
161 $wpdb->prepare(
162 " UPDATE {$instructor_table}
163 SET meta_value = %s
164 WHERE user_id IN ($user_ids)
165 AND meta_key = %s
166 ",
167 $status,
168 '_tutor_instructor_status'
169 )
170 );
171 // Remove role.
172 if ( 'pending' === $status || 'blocked' === $status ) {
173 $arr = explode( ',', $user_ids );
174 foreach ( $arr as $instructor_id ) {
175 $instructor_id = (int) sanitize_text_field( $instructor_id );
176 self::remove_instructor_role( $instructor_id, $status );
177 }
178 }
179
180 if ( 'approved' === $status ) {
181 $arr = explode( ',', $user_ids );
182 foreach ( $arr as $instructor_id ) {
183 $instructor_id = (int) sanitize_text_field( $instructor_id );
184 self::add_instructor_role( $instructor_id, $status );
185 }
186 }
187 return false === $update ? false : true;
188 }
189
190 function column_default( $item, $column_name ) {
191 switch ( $column_name ) {
192 case 'user_email':
193 case 'display_name':
194 return $item->$column_name;
195 case 'registration_date':
196 return esc_html( date( get_option( 'date_format' ), strtotime( $item->user_registered ) ) );
197 default:
198 return print_r( $item, true ); // Show the whole array for troubleshooting purposes
199 }
200 }
201
202 function column_total_course( $item ) {
203 global $wpdb;
204 $course_post_type = tutor()->course_post_type;
205
206 $total_course = (int) $wpdb->get_var(
207 $wpdb->prepare(
208 "SELECT count(ID) from {$wpdb->posts}
209 WHERE post_author=%d AND post_type=%s ",
210 $item->ID,
211 $course_post_type
212 )
213 );
214
215 echo $total_course;
216 }
217
218 /**
219 * @param $item
220 *
221 * Completed Course by User
222 */
223
224 function column_status( $item ) {
225 // Build row actions
226 $actions = array();
227
228 $status = tutor_utils()->instructor_status( $item->ID, false );
229
230 switch ( $status ) {
231 case 'pending':
232 $actions['approved'] = sprintf( '<span class="tutor-badge-label label-warning">' . __( 'Pending', 'tutor' ) . '</span>' );
233 break;
234 case 'approved':
235 $actions['blocked'] = sprintf( '<span class="tutor-badge-label label-success">' . __( 'Approved', 'tutor' ) . '</span>' );
236 break;
237 case 'blocked':
238 $actions['approved'] = sprintf( '<span class="tutor-badge-label label-danger">' . __( 'Blocked', 'tutor' ) . '</span>' );
239 break;
240 }
241
242 return $this->row_actions( $actions );
243 }
244
245 function column_display_name( $item ) {
246 // Build row actions
247 $actions = array();
248
249 $status = tutor_utils()->instructor_status( $item->ID, false );
250
251 switch ( $status ) {
252 case 'pending':
253 $actions['approved'] = sprintf( '<a class="tutor-btn tutor-btn-outline-primary instructor-action" data-action="approve" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Approve', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'approve', $item->ID );
254 break;
255 case 'approved':
256 $actions['blocked'] = sprintf( '<a data-prompt-message="' . __( 'Sure to Block?', 'tutor' ) . '" class="tutor-btn tutor-btn-outline-primary instructor-action" data-action="blocked" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Block', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'blocked', $item->ID );
257 break;
258 case 'blocked':
259 $actions['approved'] = sprintf( '<a data-prompt-message="' . __( 'Sure to Un Block?', 'tutor' ) . '" class="tutor-btn tutor-btn-outline-primary instructor-action" data-action="approve" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Unblock', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'approve', $item->ID );
260 break;
261 }
262
263 // Add user edit link
264 $edit_link = get_edit_user_link( $item->ID );
265 $edit_link = '<a href="' . esc_url( $edit_link ) . '">' . esc_html__( 'Edit' ) . '</a>';
266 $actions['tutor-instructor-edit-link'] = $edit_link;
267
268 // Add remove instructor action
269 $removal_title = $status == 'pending' ? __( 'Reject', 'tutor' ) : __( 'Remove as Instructor', 'tutor' );
270 $removal_warning = $status == 'pending' ? __( 'Sure to Reject?', 'tutor' ) : __( 'Sure to Remove as Instructor?', 'tutor' );
271 $actions['tutor-remove-instructor'] = sprintf( '<a data-prompt-message="' . $removal_warning . '" class="instructor-action" data-action="remove-instructor" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . $removal_title . '</a>', self::INSTRUCTOR_LIST_PAGE, 'remove-instructor', $item->ID );
272
273 // Return the title contents
274 return sprintf(
275 '%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
276 $item->display_name,
277 $item->ID,
278 $this->row_actions( $actions )
279 );
280 }
281
282 function column_action( $item ) {
283 // Build row actions
284 $actions = array();
285
286 $status = tutor_utils()->instructor_status( $item->ID, false );
287
288 switch ( $status ) {
289 case 'pending':
290 $actions['approved'] = sprintf( '<a class="tutor-btn tutor-btn-outline-primary instructor-action" data-action="approve" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Approve', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'approve', $item->ID );
291 break;
292 case 'approved':
293 $actions['blocked'] = sprintf( '<a data-title="' . ( '' ) . '" data-prompt-message="' . __( 'Are you sure, want to block?', 'tutor' ) . '" class="tutor-btn tutor-btn-outline-primary instructor-action" data-action="blocked" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Block', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'blocked', $item->ID );
294 break;
295 case 'blocked':
296 $actions['approved'] = sprintf( '<a data-title="' . ( '' ) . '" data-prompt-message="' . __( 'Are you sure, want to approve?', 'tutor' ) . '" class="tutor-btn tutor-btn-outline-primary instructor-action" data-action="approve" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Approve', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'approve', $item->ID );
297 break;
298 }
299
300 return $this->row_actions( $actions );
301 }
302
303 function column_cb( $item ) {
304 return sprintf(
305 '<input type="checkbox" name="%1$s[]" value="%2$s" />',
306 /*$1%s*/ $this->_args['singular'], // Let's simply repurpose the table's singular label ("instructor")
307 /*$2%s*/ $item->ID // The value of the checkbox should be the record's id
308 );
309 }
310
311 function column_instructor_commission( $item ) {
312 $commision = apply_filters( 'tutor_pro_instructor_commission_string', $item->ID );
313
314 // If the return value is numeric, it means the filter was not executed.
315 // may be pro is not installed. So show N\A. The return value will something like '23 percent'
316
317 return ! is_numeric( $commision ) ? $commision : 'N\\A';
318 }
319
320 function get_columns() {
321 $columns = array(
322 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
323 'display_name' => __( 'Name', 'tutor' ),
324 'user_email' => __( 'E-Mail', 'tutor' ),
325 'total_course' => __( 'Total Course', 'tutor' ),
326 'instructor_commission' => __( 'Instructor Commission', 'tutor' ),
327 'registration_date' => __( 'Date', 'tutor' ),
328 'status' => __( 'Status', 'tutor' ),
329 );
330 return $columns;
331 }
332
333 function get_sortable_columns() {
334 $sortable_columns = array(
335 // 'display_name' => array('title',false), //true means it's already sorted
336 );
337 return $sortable_columns;
338 }
339
340 /**
341 * Handle single instructor approve | block action
342 */
343 function process_bulk_action() {
344 $instructor_id = (int) sanitize_text_field( $_GET['instructor'] );
345 if ( 'approve' === $this->current_action() ) {
346 self::add_instructor_role( $instructor_id, 'approved' );
347 }
348
349 if ( 'blocked' === $this->current_action() ) {
350 self::add_instructor_role( $instructor_id, 'blocked' );
351 }
352 }
353
354 /**
355 * Filter support added
356 *
357 * @param optional
358 *
359 * @since 1.9.7
360 */
361 function prepare_items( $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '' ) {
362 $per_page = 20;
363
364 // $search_term = '';
365 // if (isset($_REQUEST['s'])){
366 // $search_term = sanitize_text_field($_REQUEST['s']);
367 // }
368
369 $columns = $this->get_columns();
370 $hidden = array();
371 $sortable = $this->get_sortable_columns();
372
373 $this->_column_headers = array( $columns, $hidden, $sortable );
374 $this->process_bulk_action();
375 $current_page = $this->get_pagenum();
376
377 $total_items = tutor_utils()->get_total_instructors( $search_filter );
378 $this->items = tutor_utils()->get_instructors( ( $current_page - 1 ) * $per_page, $per_page, $search_filter, $course_filter, $date_filter, $order_filter, $status = null, $cat_ids = array() );
379
380 $this->set_pagination_args(
381 array(
382 'total_items' => $total_items,
383 'per_page' => $per_page,
384 'total_pages' => ceil( $total_items / $per_page ),
385 )
386 );
387 }
388
389 /**
390 * Initialize instructor_role to a user
391 *
392 * @param int $instructor_id | user id that need to add role.
393 * @param string $status | status that will added with role (approved).
394 * @return void
395 */
396 protected static function add_instructor_role( int $instructor_id, string $status ) {
397 $instructor_id = sanitize_text_field( $instructor_id );
398 $status = sanitize_text_field( $status );
399
400 do_action( 'tutor_before_approved_instructor', $instructor_id );
401
402 update_user_meta( $instructor_id, '_tutor_instructor_status', $status );
403 update_user_meta( $instructor_id, '_tutor_instructor_approved', tutor_time() );
404
405 $instructor = new \WP_User( $instructor_id );
406 $instructor->add_role( tutor()->instructor_role );
407
408 // TODO: send E-Mail to this user about instructor approval, should via hook.
409 do_action( 'tutor_after_approved_instructor', $instructor_id );
410 }
411
412 /**
413 * Initialize instructor_role to a user
414 *
415 * @param int $instructor_id | user id that need to add role.
416 * @param string $status | status that will added with role (approved).
417 * @return void
418 */
419 protected static function remove_instructor_role( int $instructor_id, string $status ) {
420 $instructor_id = sanitize_text_field( $instructor_id );
421 $status = sanitize_text_field( $status );
422
423 do_action( 'tutor_before_blocked_instructor', $instructor_id );
424 update_user_meta( $instructor_id, '_tutor_instructor_status', $status );
425
426 $instructor = new \WP_User( $instructor_id );
427 $instructor->remove_role( tutor()->instructor_role );
428 do_action( 'tutor_after_blocked_instructor', $instructor_id );
429 }
430
431 }
432