PluginProbe
Tutor LMS – eLearning and online course solution / 2.2.1
Tutor LMS – eLearning and online course solution v2.2.1
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/User.php +28 -613 trunk2.2.1 View file →
@@ -9,15 +9,12 @@
9 9 */
10 10
11 11 namespace TUTOR;
12 12
13 -defined( 'ABSPATH' ) || exit;
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
15 +}
14 16
15 -use Tutor\Helpers\HttpHelper;
16 -use Tutor\Models\UserModel;
17 -use Tutor\Traits\JsonResponse;
18 -use TUTOR\InstructorList;
19 -
20 17 /**
21 18 * User class
22 19 *
23 20 * @since 1.0.0
@@ -22,9 +19,8 @@
22 19 *
23 20 * @since 1.0.0
24 21 */
25 22 class User {
26 - use JsonResponse;
27 23
28 24 const STUDENT = 'subscriber';
29 25 const INSTRUCTOR = 'tutor_instructor';
30 26 const ADMIN = 'administrator';
@@ -29,53 +25,8 @@
29 25 const INSTRUCTOR = 'tutor_instructor';
30 26 const ADMIN = 'administrator';
31 27
32 28 /**
33 - * User meta keys.
34 - */
35 - const REVIEW_POPUP_META = 'tutor_review_course_popup';
36 - const LAST_LOGIN_META = 'tutor_last_login';
37 - const TIMEZONE_META = '_tutor_timezone';
38 - const PROFILE_PHOTO_META = '_tutor_profile_photo';
39 - const PHONE_NUMBER_META = 'phone_number';
40 - const COVER_PHOTO_META = '_tutor_cover_photo';
41 - const PROFILE_BIO_META = '_tutor_profile_bio';
42 - const PROFILE_JOB_TITLE_META = '_tutor_profile_job_title';
43 - const TUTOR_STUDENT_META = '_is_tutor_student';
44 - const TOUR_COMPLETED_META = '_tutor_tour_completed';
45 - const APPLICATION_SOURCE_META = '_tutor_application_source';
46 - const INSTRUCTOR_APPROVAL_NOTICE_META = 'tutor_instructor_show_approval_message';
47 -
48 - const SOURCE_INSTRUCTOR_REGISTRATION = 'instructor_registration';
49 - const SOURCE_STUDENT_DASHBOARD = 'student_dashboard';
50 -
51 - /**
52 - * View as constants
53 - *
54 - * @since 4.0.0
55 - */
56 - const VIEW_AS_INSTRUCTOR = 'instructor';
57 - const VIEW_AS_STUDENT = 'student';
58 -
59 - /**
60 - * User meta key for storing view as mode
61 - *
62 - * @since 4.0.0
63 - *
64 - * @var string
65 - */
66 - const VIEW_MODE_USER_META = 'tutor_profile_view_mode';
67 -
68 - /**
69 - * User model
70 - *
71 - * @since 3.0.0
72 - *
73 - * @var UserModel
74 - */
75 - private $model;
76 -
77 - /**
78 29 * Registration notice
79 30 *
80 31 * @since 1.0.0
81 32 *
@@ -93,9 +44,8 @@
93 44 *
94 45 * @return void
95 46 */
96 47 public function __construct( $register_hooks = true ) {
97 - $this->model = new UserModel();
98 48 if ( ! $register_hooks ) {
99 49 return;
100 50 }
101 51
@@ -109,33 +59,11 @@
109 59 add_action( 'wp_ajax_tutor_user_photo_upload', array( $this, 'update_user_photo' ) );
110 60
111 61 add_action( 'admin_notices', array( $this, 'show_registration_disabled' ) );
112 62 add_action( 'admin_init', array( $this, 'hide_notices' ) );
113 - add_action( 'wp_login', array( $this, 'update_user_last_login' ), 10, 2 );
114 - add_action( 'login_form', array( $this, 'add_timezone_input' ) );
115 - add_action( 'wp_login', array( $this, 'set_timezone' ), 10, 2 );
116 -
117 - add_action( 'wp_ajax_tutor_user_list', array( $this, 'ajax_user_list' ) );
118 - add_action( 'wp_ajax_tutor_switch_profile', array( $this, 'ajax_switch_profile' ) );
119 - add_action( 'wp_ajax_tutor_complete_tour', array( $this, 'ajax_complete_tour' ) );
120 -
121 - add_filter( 'retrieve_password_message', array( $this, 'maybe_update_password_reset_link' ), 10, 3 );
122 63 }
123 64
124 65 /**
125 - * Get meta key name for review popup.
126 - *
127 - * @since 2.4.0
128 - *
129 - * @param int $course_id course id.
130 - *
131 - * @return string user meta key name.
132 - */
133 - public static function get_review_popup_meta( $course_id ) {
134 - return self::REVIEW_POPUP_META . '_' . $course_id;
135 - }
136 -
137 - /**
138 66 * Check user has provided role.
139 67 *
140 68 * @since 2.2.0
141 69 *
@@ -147,40 +75,18 @@
147 75 return current_user_can( $role );
148 76 }
149 77
150 78 /**
151 - * Check current user has capability.
152 - *
153 - * Example usage:
154 - *
155 - * User::can( 'edit_posts' );
156 - * User::can( 'edit_post', $post->ID );
157 - * User::can( 'edit_post_meta', $post->ID, $meta_key );
158 - *
159 - * @since 4.0.0
160 - *
161 - * @param string $capability capability.
162 - * @param mixed ...$args args.
163 - *
164 - * @return boolean
165 - */
166 - public static function can( string $capability = 'manage_options', ...$args ) {
167 - return current_user_can( $capability, ...$args );
168 - }
169 -
170 - /**
171 79 * Check user has any role.
172 80 *
173 81 * @since 2.2.0
174 - * @since 2.6.2 $user_id param added.
175 82 *
176 83 * @param array $roles roles.
177 - * @param int $user_id user id.
178 84 *
179 85 * @return boolean
180 86 */
181 - public static function has_any_role( array $roles, $user_id = 0 ) {
182 - $user = get_userdata( tutor_utils()->get_user_id( $user_id ) );
87 + public static function has_any_role( array $roles ) {
88 + $user = wp_get_current_user();
183 89 if ( empty( $user->roles ) || empty( $roles ) ) {
184 90 return false;
185 91 }
186 92
@@ -186,8 +92,9 @@
186 92
187 93 foreach ( $roles as $role ) {
188 94 if ( in_array( $role, $user->roles, true ) ) {
189 95 return true;
96 + break;
190 97 }
191 98 }
192 99
193 100 return false;
@@ -196,17 +103,13 @@
196 103 /**
197 104 * Check user is student.
198 105 *
199 106 * @since 2.2.0
200 - * @since 2.6.2 $user_id param added.
201 107 *
202 - * @param int $user_id user id.
203 - *
204 108 * @return boolean
205 109 */
206 - public static function is_student( $user_id = 0 ) {
207 - $is_tutor_student = get_user_meta( tutor_utils()->get_user_id( $user_id ), self::TUTOR_STUDENT_META, true );
208 - return $is_tutor_student ? true : false;
110 + public static function is_student() {
111 + return current_user_can( self::STUDENT );
209 112 }
210 113
211 114 /**
212 115 * Check user is admin.
@@ -211,16 +114,13 @@
211 114 /**
212 115 * Check user is admin.
213 116 *
214 117 * @since 2.2.0
215 - * @since 3.2.0 user_id param added.
216 118 *
217 - * @param int $user_id user id.
218 - *
219 119 * @return boolean
220 120 */
221 - public static function is_admin( $user_id = 0 ) {
222 - return user_can( tutor_utils()->get_user_id( $user_id ), self::ADMIN );
121 + public static function is_admin() {
122 + return current_user_can( self::ADMIN );
223 123 }
224 124
225 125 /**
226 126 * Check current user is instructor.
@@ -225,104 +125,18 @@
225 125 /**
226 126 * Check current user is instructor.
227 127 *
228 128 * @since 2.2.0
229 - * @since 3.2.0 user_id param added.
230 129 *
231 - * @param int $user_id user id.
232 130 * @param bool $is_approved instructor is approved or not.
233 - *
131 + *
234 132 * @return boolean
235 133 */
236 - public static function is_instructor( $user_id = 0, $is_approved = true ) {
237 - return tutils()->is_instructor( $user_id, $is_approved );
134 + public static function is_instructor( $is_approved = true ) {
135 + return tutils()->is_instructor( 0, $is_approved );
238 136 }
239 137
240 138 /**
241 - * Get Tutor application source for a user.
242 - *
243 - * @since 4.0.0
244 - *
245 - * @param int $user_id user id.
246 - *
247 - * @return string
248 - */
249 - public static function get_application_source( $user_id = 0 ): string {
250 - return (string) get_user_meta(
251 - tutor_utils()->get_user_id( $user_id ),
252 - self::APPLICATION_SOURCE_META,
253 - true
254 - );
255 - }
256 -
257 - /**
258 - * Check if the user came through instructor registration.
259 - *
260 - * @since 4.0.0
261 - *
262 - * @param int $user_id user id.
263 - *
264 - * @return boolean
265 - */
266 - public static function used_instructor_registration( $user_id = 0 ): bool {
267 - return self::SOURCE_INSTRUCTOR_REGISTRATION === self::get_application_source( $user_id );
268 - }
269 -
270 - /**
271 - * Check if a user can view instructor dashboard screens.
272 - *
273 - * @since 4.0.0
274 - *
275 - * @param int $user_id user id.
276 - *
277 - * @return boolean
278 - */
279 - public static function can_view_instructor_dashboard( $user_id = 0 ): bool {
280 - $user_id = tutor_utils()->get_user_id( $user_id );
281 -
282 - if ( self::is_admin( $user_id ) || self::is_instructor( $user_id ) ) {
283 - return true;
284 - }
285 -
286 - if ( ! self::used_instructor_registration( $user_id ) ) {
287 - return false;
288 - }
289 -
290 - return in_array(
291 - tutor_utils()->instructor_status( $user_id, false ),
292 - array( Instructors_List::STATUS_PENDING, Instructors_List::STATUS_APPROVED ),
293 - true
294 - );
295 - }
296 -
297 - /**
298 - * Check if user has a pending instructor application.
299 - *
300 - * @since 4.0.0
301 - *
302 - * @param int $user_id user id.
303 - *
304 - * @return boolean
305 - */
306 - public static function has_pending_instructor_application( $user_id = 0 ): bool {
307 - return Instructors_List::STATUS_PENDING === tutor_utils()->instructor_status( $user_id, false );
308 - }
309 -
310 - /**
311 - * Check current user is only instructor as admin also has instructor role.
312 - *
313 - * @since 3.2.0
314 - *
315 - * @param int $user_id user id.
316 - * @param bool $is_approved instructor is approved or not.
317 - *
318 - * @return boolean
319 - */
320 - public static function is_only_instructor( $user_id = 0, $is_approved = true ) {
321 - return ! self::is_admin( $user_id ) && self::is_instructor( $user_id, $is_approved );
322 - }
323 -
324 - /**
325 139 * Profile layouts
326 140 *
327 141 * @since 1.0.0
328 142 *
@@ -359,15 +173,9 @@
359 173 */
360 174 private function delete_existing_user_photo( $user_id, $type ) {
361 175 $meta_key = 'cover_photo' == $type ? '_tutor_cover_photo' : '_tutor_profile_photo';
362 176 $photo_id = get_user_meta( $user_id, $meta_key, true );
363 - if ( is_numeric( $photo_id ) ) {
364 - $attachment = get_post( $photo_id );
365 - $post_author = (int) $attachment->post_author ?? 0;
366 - if ( $user_id === $post_author ) {
367 - wp_delete_attachment( $photo_id, true );
368 - }
369 - }
177 + is_numeric( $photo_id ) ? wp_delete_attachment( $photo_id, true ) : 0;
370 178 delete_user_meta( $user_id, $meta_key );
371 179 }
372 180
373 181 /**
@@ -401,9 +209,9 @@
401 209
402 210 /**
403 211 * Photo Update from profile
404 212 */
405 - $photo = tutor_utils()->array_get( 'photo_file', $_FILES ); //phpcs:ignore -- already sanitized.
213 + $photo = tutor_utils()->array_get( 'photo_file', $_FILES );
406 214 $photo_size = tutor_utils()->array_get( 'size', $photo );
407 215 $photo_type = tutor_utils()->array_get( 'type', $photo );
408 216
409 217 if ( $photo_size && strpos( $photo_type, 'image' ) !== false ) {
@@ -451,32 +259,8 @@
451 259 }
452 260 }
453 261
454 262 /**
455 - * Get user timezone string.
456 - *
457 - * @param int|object $user user id or user object. Default: current user.
458 - *
459 - * @return string user timezone string, fallback site timezone string.
460 - */
461 - public static function get_user_timezone_string( $user = 0 ) {
462 - if ( is_numeric( $user ) ) {
463 - $user = get_user_by( 'id', tutor_utils()->get_user_id( $user ) );
464 - }
465 -
466 - if ( ! is_a( $user, 'WP_User' ) ) {
467 - return wp_timezone_string();
468 - }
469 -
470 - $timezone = get_user_meta( $user->ID, self::TIMEZONE_META, true );
471 - if ( self::is_admin() || empty( $timezone ) ) {
472 - $timezone = wp_timezone_string();
473 - }
474 -
475 - return $timezone;
476 - }
477 -
478 - /**
479 263 * Profile update
480 264 *
481 265 * @since 1.0.0
482 266 *
@@ -484,21 +268,19 @@
484 268 *
485 269 * @return void
486 270 */
487 271 public function profile_update( $user_id ) {
488 - if ( 'tutor_profile_update_by_wp' !== Input::post( 'tutor_action' ) ) {
272 + if ( tutor_utils()->array_get( 'tutor_action', $_POST ) !== 'tutor_profile_update_by_wp' ) {
489 273 return;
490 274 }
491 275
492 - $timezone = Input::post( 'timezone', '' );
493 - $_tutor_profile_job_title = Input::post( self::PROFILE_JOB_TITLE_META, '' );
494 - $_tutor_profile_bio = Input::post( self::PROFILE_BIO_META, '', Input::TYPE_KSES_POST );
495 - $_tutor_profile_image = Input::post( self::PROFILE_PHOTO_META, '', Input::TYPE_KSES_POST );
276 + $_tutor_profile_job_title = Input::post( '_tutor_profile_job_title', '' );
277 + $_tutor_profile_bio = Input::post( '_tutor_profile_bio', '', Input::TYPE_KSES_POST );
278 + $_tutor_profile_image = Input::post( '_tutor_profile_photo', '', Input::TYPE_KSES_POST );
496 279
497 - update_user_meta( $user_id, self::PROFILE_JOB_TITLE_META, $_tutor_profile_job_title );
498 - update_user_meta( $user_id, self::PROFILE_BIO_META, $_tutor_profile_bio );
499 - update_user_meta( $user_id, self::PROFILE_PHOTO_META, $_tutor_profile_image );
500 - update_user_meta( $user_id, self::TIMEZONE_META, $timezone );
280 + update_user_meta( $user_id, '_tutor_profile_job_title', $_tutor_profile_job_title );
281 + update_user_meta( $user_id, '_tutor_profile_bio', $_tutor_profile_bio );
282 + update_user_meta( $user_id, '_tutor_profile_photo', $_tutor_profile_image );
501 283 }
502 284
503 285 /**
504 286 * Set user role
@@ -528,11 +310,9 @@
528 310 */
529 311 public function hide_notices() {
530 312 $hide_notice = Input::get( 'tutor-hide-notice', '' );
531 313 $is_register_enabled = Input::get( 'tutor-registration', '' );
532 - $has_manage_cap = current_user_can( 'manage_options' );
533 -
534 - if ( $has_manage_cap && is_admin() && 'registration' === $hide_notice ) {
314 + if ( is_admin() && 'registration' === $hide_notice ) {
535 315 tutor_utils()->checking_nonce( 'get' );
536 316
537 317 if ( 'enable' === $is_register_enabled ) {
538 318 update_option( 'users_can_register', 1 );
@@ -537,9 +317,9 @@
537 317 if ( 'enable' === $is_register_enabled ) {
538 318 update_option( 'users_can_register', 1 );
539 319 } else {
540 320 self::$hide_registration_notice = true;
541 - setcookie( 'tutor_notice_hide_registration', 1, time() + MONTH_IN_SECONDS, tutor()->basepath );
321 + setcookie( 'tutor_notice_hide_registration', 1, time() + ( 86400 * 30 ), tutor()->basepath );
542 322 }
543 323 }
544 324 }
545 325
@@ -551,9 +331,10 @@
551 331 * @return void
552 332 */
553 333 public function show_registration_disabled() {
554 334 if ( self::$hide_registration_notice ||
555 - ( '0' !== get_option( 'users_can_register' ) ) ||
335 + ! tutor_utils()->is_tutor_dashboard() ||
336 + get_option( 'users_can_register' ) ||
556 337 isset( $_COOKIE['tutor_notice_hide_registration'] ) ||
557 338 ! current_user_can( 'manage_options' )
558 339 ) {
559 340 return;
@@ -566,19 +347,12 @@
566 347 <div>
567 348 <img src="<?php echo esc_url( tutor()->url . 'assets/images/icon-info-round.svg' ); ?>"/>
568 349 </div>
569 350 <div>
570 - <?php
571 - echo wp_kses(
572 - __( 'As membership is turned off, students and instructors will not be able to sign up. <strong>Press Enable</strong> or go to <strong>Settings > General > Membership</strong> and enable "Anyone can register".', 'tutor' ),
573 - array( 'strong' => true )
574 - );
575 - ?>
351 + <?php echo wp_kses( 'As membership is turned off, students and instructors will not be able to sign up. <strong>Press Enable</strong> or go to <strong>Settings > General > Membership</strong> and enable "Anyone can register".', array( 'strong' => true ) ); ?>
576 352 </div>
577 353 <div>
578 - <a href="<?php echo esc_url( add_query_arg( 'tutor-registration', 'enable', $hide_url ) ); ?>">
579 - <?php esc_html_e( 'Enable', 'tutor' ); ?>
580 - </a>
354 + <a href="<?php echo esc_url( add_query_arg( 'tutor-registration', 'enable', $hide_url ) ); ?>"><?php esc_html_e( 'Enable', 'tutor' ); ?></a>
581 355 <hr/>
582 356 <a href="<?php echo esc_url( $hide_url ); ?>">
583 357 <?php esc_html_e( 'Dismiss', 'tutor' ); ?>
584 358 </a>
@@ -585,365 +359,6 @@
585 359 </div>
586 360 </div>
587 361 </div>
588 362 <?php
589 - }
590 -
591 - /**
592 - * Set the user last active timestamp to now.
593 - *
594 - * @since 2.5.0
595 - *
596 - * @param string $user_login active user name.
597 - * @param \WP_User $user User object data.
598 - *
599 - * @return void
600 - */
601 - public function update_user_last_login( $user_login, $user ) {
602 - update_user_meta( $user->ID, self::LAST_LOGIN_META, time() );
603 - }
604 -
605 - /**
606 - * Add timezone input field to login form.
607 - *
608 - * @since 3.0.0
609 - */
610 - public function add_timezone_input() {
611 - ?>
612 - <input type="hidden" name="timezone" value="<?php echo esc_attr( wp_timezone_string() ); ?>" />
613 - <script>
614 - document.addEventListener('DOMContentLoaded', function() {
615 - const timezone = document.querySelector('input[name="timezone"]');
616 - if ( timezone) {
617 - const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
618 - timezone.value = tz
619 - }
620 - });
621 - </script>
622 - <?php
623 - }
624 -
625 - /**
626 - * Set user timezone if not it set.
627 - *
628 - * @since 3.0.0
629 - *
630 - * @param string $user_login active user name.
631 - * @param \WP_User $user User object data.
632 - *
633 - * @return void
634 - */
635 - public function set_timezone( $user_login, $user ) {
636 - if ( Input::has( 'timezone' ) ) {
637 - $timezone = get_user_meta( $user->ID, self::TIMEZONE_META, true );
638 - if ( empty( $timezone ) ) {
639 - update_user_meta( $user->ID, self::TIMEZONE_META, Input::post( 'timezone', wp_timezone_string() ) );
640 - }
641 - }
642 - }
643 -
644 - /**
645 - * Get profile settings data
646 - *
647 - * @since 4.0.0
648 - *
649 - * @param int $user_id user id.
650 - *
651 - * @return array
652 - */
653 - public static function get_profile_settings_data( $user_id = 0 ) {
654 - $user_id = tutor_utils()->get_user_id( $user_id );
655 - $user = get_userdata( $user_id );
656 -
657 - // Prepare profile pic.
658 - $profile_placeholder = apply_filters( 'tutor_login_default_avatar', tutor()->url . 'assets/images/profile-photo.png' );
659 - $profile_photo_src = $profile_placeholder;
660 - $profile_photo_id = get_user_meta( $user->ID, self::PROFILE_PHOTO_META, true );
661 -
662 - if ( $profile_photo_id ) {
663 - $url = wp_get_attachment_image_url( $profile_photo_id, 'full' );
664 - if ( ! empty( $url ) ) {
665 - $profile_photo_src = $url;
666 - }
667 - }
668 -
669 - $timezone = self::get_user_timezone_string( $user );
670 -
671 - // Prepare cover photo.
672 - $cover_placeholder = tutor()->url . 'assets/images/cover-photo.webp';
673 - $cover_photo_src = $cover_placeholder;
674 - $cover_photo_id = get_user_meta( $user->ID, self::COVER_PHOTO_META, true );
675 -
676 - if ( $cover_photo_id ) {
677 - $url = wp_get_attachment_image_url( $cover_photo_id, 'full' );
678 - if ( ! empty( $url ) ) {
679 - $cover_photo_src = $url;
680 - }
681 - }
682 -
683 - // Prepare display name.
684 - $public_display = array();
685 - $public_display['display_nickname'] = $user->nickname;
686 - $public_display['display_username'] = $user->user_login;
687 -
688 - if ( ! empty( $user->first_name ) ) {
689 - $public_display['display_firstname'] = $user->first_name;
690 - }
691 -
692 - if ( ! empty( $user->last_name ) ) {
693 - $public_display['display_lastname'] = $user->last_name;
694 - }
695 -
696 - if ( ! empty( $user->first_name ) && ! empty( $user->last_name ) ) {
697 - $public_display['display_firstlast'] = $user->first_name . ' ' . $user->last_name;
698 - $public_display['display_lastfirst'] = $user->last_name . ' ' . $user->first_name;
699 - }
700 -
701 - if ( ! in_array( $user->display_name, $public_display, true ) ) { // Only add this if it isn't duplicated elsewhere.
702 - $public_display = array( 'display_displayname' => $user->display_name ) + $public_display;
703 - }
704 -
705 - $public_display = array_map( 'trim', $public_display );
706 - $public_display = array_unique( $public_display );
707 - $max_filesize = floatval( ini_get( 'upload_max_filesize' ) ) * ( 1024 * 1024 );
708 -
709 - $profile_bio = wp_kses_post( get_user_meta( $user->ID, self::PROFILE_BIO_META, true ) );
710 - $job_title = get_user_meta( $user->ID, self::PROFILE_JOB_TITLE_META, true );
711 - $phone = get_user_meta( $user->ID, self::PHONE_NUMBER_META, true );
712 -
713 - return array(
714 - 'user' => $user,
715 - 'profile_placeholder' => $profile_placeholder,
716 - 'profile_photo_src' => $profile_photo_src,
717 - 'profile_photo_id' => $profile_photo_id,
718 - 'cover_placeholder' => $cover_placeholder,
719 - 'cover_photo_src' => $cover_photo_src,
720 - 'cover_photo_id' => $cover_photo_id,
721 - 'timezone' => $timezone,
722 - 'public_display' => $public_display,
723 - 'max_filesize' => $max_filesize,
724 - 'profile_bio' => $profile_bio,
725 - 'job_title' => $job_title,
726 - 'phone_number' => $phone,
727 - );
728 - }
729 -
730 - /**
731 - * Get user list with pagination & support
732 - * search term
733 - *
734 - * @since 3.0.0
735 - *
736 - * @return void
737 - */
738 - public function ajax_user_list() {
739 - tutor_utils()->check_nonce();
740 -
741 - $can_access = apply_filters( 'tutor_user_list_access', current_user_can( 'manage_options' ) );
742 - if ( ! $can_access ) {
743 - $this->json_response( tutor_utils()->error_message( 'forbidden' ), HttpHelper::STATUS_FORBIDDEN );
744 - }
745 -
746 - $response = array(
747 - 'results' => array(),
748 - 'total_items' => 0,
749 - );
750 -
751 - $limit = Input::post( 'limit', 10, Input::TYPE_INT );
752 - $offset = Input::post( 'offset', 0, Input::TYPE_INT );
753 -
754 - $args = array(
755 - 'limit' => $limit,
756 - 'offset' => $offset,
757 - );
758 -
759 - $filter = json_decode( wp_unslash( $_POST['filter'] ?? '{}' ) );//phpcs:ignore
760 - if ( ! empty( $filter ) && property_exists( $filter, 'search' ) && ! empty( $filter->search ) ) {
761 - $args['search'] = '*' . Input::sanitize( $filter->search ) . '*';
762 - $args['search_columns'] = array( 'user_login', 'user_email', 'user_nicename', 'display_name', 'ID' );
763 - }
764 -
765 - $user_list = $this->model->get_users_list( $args );
766 -
767 - if ( is_object( $user_list ) ) {
768 - foreach ( $user_list->get_results() as $user ) {
769 - // Set user avatar.
770 - $user->avatar_url = get_avatar_url( $user->ID, array( 'size' => 32 ) );
771 - $response['results'][] = $user;
772 - }
773 -
774 - $response['total_items'] = $user_list->get_total();
775 - }
776 -
777 - $this->json_response(
778 - __( 'User list fetched successfully!', 'tutor' ),
779 - $response
780 - );
781 - }
782 -
783 - /**
784 - * Switch user profile ajax-handler
785 - *
786 - * @since 4.0.0
787 - *
788 - * @return void send wp_json response
789 - */
790 - public function ajax_switch_profile() {
791 - tutor_utils()->checking_nonce();
792 -
793 - $user_id = get_current_user_id();
794 - if ( ! self::can_switch_mode( $user_id ) ) {
795 - $this->json_response(
796 - tutor_utils()->error_message(),
797 - null,
798 - HttpHelper::STATUS_UNAUTHORIZED
799 - );
800 - }
801 -
802 - $switch_mode = '';
803 - $switch_label = '';
804 - $current_mode = Input::post( 'current_mode' );
805 -
806 - if ( ! in_array( $current_mode, array( self::VIEW_AS_INSTRUCTOR, self::VIEW_AS_STUDENT ), true ) ) {
807 - $this->response_bad_request( tutor_utils()->error_message( 'invalid_req' ) );
808 - }
809 -
810 - if ( self::VIEW_AS_INSTRUCTOR === $current_mode ) {
811 - $switch_mode = self::VIEW_AS_STUDENT;
812 - $switch_label = __( 'Student', 'tutor' );
813 - } elseif ( self::VIEW_AS_STUDENT === $current_mode ) {
814 - $switch_mode = self::VIEW_AS_INSTRUCTOR;
815 - $switch_label = __( 'Instructor', 'tutor' );
816 - }
817 -
818 - update_user_meta( $user_id, self::VIEW_MODE_USER_META, $switch_mode );
819 -
820 - // translators:%s for switching mode.
821 - $this->response_success( sprintf( __( 'Profile switched to %s!', 'tutor' ), $switch_label ) );
822 - }
823 -
824 - /**
825 - * Get current view mode STUDENT/INSTRUCTOR
826 - *
827 - * @since 4.0.0
828 - *
829 - * @return string
830 - */
831 - public static function get_current_view_mode(): string {
832 - $user_id = get_current_user_id();
833 - $can_switch = self::can_switch_mode( $user_id );
834 - $default_mode = $can_switch ? self::VIEW_AS_INSTRUCTOR : self::VIEW_AS_STUDENT;
835 - $current_mode = get_user_meta( $user_id, self::VIEW_MODE_USER_META, true );
836 -
837 - if ( $can_switch && in_array( $current_mode, array( self::VIEW_AS_INSTRUCTOR, self::VIEW_AS_STUDENT ), true ) ) {
838 - return $current_mode;
839 - }
840 -
841 - if ( self::used_instructor_registration( $user_id ) ) {
842 - $instructor_status = tutor_utils()->instructor_status( $user_id, false );
843 - if ( in_array( $instructor_status, array( Instructors_List::STATUS_PENDING, Instructors_List::STATUS_APPROVED ), true ) ) {
844 - return self::VIEW_AS_INSTRUCTOR;
845 - }
846 - }
847 -
848 - return $default_mode;
849 - }
850 -
851 - /**
852 - * Check if the user is in instructor view
853 - *
854 - * @since 4.0.0
855 - *
856 - * @return bool
857 - */
858 - public static function is_instructor_view(): bool {
859 - return self::VIEW_AS_INSTRUCTOR === self::get_current_view_mode();
860 - }
861 -
862 - /**
863 - * Check if the user is in student view
864 - *
865 - * @since 4.0.0
866 - *
867 - * @return bool
868 - */
869 - public static function is_student_view(): bool {
870 - return self::VIEW_AS_STUDENT === self::get_current_view_mode();
871 - }
872 -
873 - /**
874 - * Check if the user can switch between learner and instructor dashboard modes.
875 - *
876 - * @since 4.0.0
877 - *
878 - * @param int $user_id User ID.
879 - *
880 - * @return bool
881 - */
882 - public static function can_switch_mode( int $user_id = 0 ): bool {
883 - return self::is_admin( $user_id ) || self::is_instructor( $user_id );
884 - }
885 -
886 - /**
887 - * Mark dashboard tour as completed for the current user.
888 - *
889 - * @since 4.0.0
890 - *
891 - * @return void JSON response.
892 - */
893 - public function ajax_complete_tour() {
894 - tutor_utils()->check_nonce();
895 -
896 - update_user_meta( get_current_user_id(), self::TOUR_COMPLETED_META, true );
897 -
898 - $this->json_response( __( 'Tour completed', 'tutor' ) );
899 - }
900 -
901 - /**
902 - * If user don't have pro and using tutor login then change the password
903 - * reset email link
904 - *
905 - * @since 4.0.2
906 - *
907 - * @param string $message Email message.
908 - * @param string $key Reset key.
909 - * @param string $user_login User login name.
910 - *
911 - * @return string
912 - */
913 - public function maybe_update_password_reset_link( $message, $key, $user_login ) {
914 - if ( tutor()->has_pro && tutor_utils()->is_addon_enabled( 'tutor-email' ) ) {
915 - return $message;
916 - }
917 -
918 - $is_tutor_login_enabled = tutor_utils()->get_option( 'enable_tutor_native_login', false );
919 - if ( ! $is_tutor_login_enabled ) {
920 - return $message;
921 - }
922 -
923 - $default_url = add_query_arg(
924 - array(
925 - 'login' => $user_login,
926 - 'key' => $key,
927 - 'action' => 'rp',
928 - ),
929 - network_site_url( 'wp-login.php' )
930 - );
931 -
932 - $user = get_user_by( 'login', $user_login );
933 - if ( ! $user ) {
934 - return $message;
935 - }
936 -
937 - $tutor_reset_url = add_query_arg(
938 - array(
939 - 'reset_key' => $key,
940 - 'user_id' => $user->ID,
941 - ),
942 - tutor_utils()->tutor_dashboard_url( 'retrieve-password' )
943 - );
944 -
945 - $message = str_replace( $default_url, $tutor_reset_url, $message );
946 -
947 - return $message;
948 363 }
949 364 }