PluginProbe
Tutor LMS – eLearning and online course solution / 1.8.10
Tutor LMS – eLearning and online course solution v1.8.10
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 +75 -889 trunk1.8.10 View file →
@@ -1,949 +1,135 @@
1 1 <?php
2 -/**
3 - * Manage user
4 - *
5 - * @package Tutor\User
6 - * @author Themeum <support@themeum.com>
7 - * @link https://themeum.com
8 - * @since 1.0.0
9 - */
10 2
11 3 namespace TUTOR;
12 4
13 -defined( 'ABSPATH' ) || exit;
5 +if ( ! defined( 'ABSPATH' ) )
6 + exit;
14 7
15 -use Tutor\Helpers\HttpHelper;
16 -use Tutor\Models\UserModel;
17 -use Tutor\Traits\JsonResponse;
18 -use TUTOR\InstructorList;
19 8
20 -/**
21 - * User class
22 - *
23 - * @since 1.0.0
24 - */
25 9 class User {
26 - use JsonResponse;
27 10
28 - const STUDENT = 'subscriber';
29 - const INSTRUCTOR = 'tutor_instructor';
30 - const ADMIN = 'administrator';
11 + public function __construct() {
12 + add_action('edit_user_profile', array($this, 'edit_user_profile'));
13 + add_action('show_user_profile', array($this, 'edit_user_profile'), 10, 1);
31 14
32 - /**
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';
15 + add_action('profile_update', array($this, 'profile_update'));
16 + add_action('set_user_role', array($this, 'set_user_role'), 10, 3);
47 17
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 - * Registration notice
79 - *
80 - * @since 1.0.0
81 - *
82 - * @var boolean
83 - */
84 - private static $hide_registration_notice = false;
85 -
86 - /**
87 - * Register hooks
88 - *
89 - * @since 1.0.0
90 - * @since 2.2.0 $register_hooks param added to resuse the class without hooks register.
91 - *
92 - * @param bool $register_hooks register hooks.
93 - *
94 - * @return void
95 - */
96 - public function __construct( $register_hooks = true ) {
97 - $this->model = new UserModel();
98 - if ( ! $register_hooks ) {
99 - return;
100 - }
101 -
102 - add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
103 - add_action( 'show_user_profile', array( $this, 'edit_user_profile' ), 10, 1 );
104 -
105 - add_action( 'profile_update', array( $this, 'profile_update' ) );
106 - add_action( 'set_user_role', array( $this, 'set_user_role' ), 10, 3 );
107 -
108 - add_action( 'wp_ajax_tutor_user_photo_remove', array( $this, 'tutor_user_photo_remove' ) );
109 - add_action( 'wp_ajax_tutor_user_photo_upload', array( $this, 'update_user_photo' ) );
110 -
111 - add_action( 'admin_notices', array( $this, 'show_registration_disabled' ) );
112 - 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 );
18 + add_action('wp_ajax_tutor_user_photo_remove', array($this, 'tutor_user_photo_remove'));
19 + add_action('wp_ajax_tutor_user_photo_upload', array($this, 'update_user_photo'));
20 +
21 + add_action('tutor_options_after_instructors', array($this, 'tutor_instructor_profile_layout'));
22 + // add_action('tutor_options_after_students', array($this, 'tutor_student_profile_layout'));
122 23 }
123 24
124 - /**
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 - * Check user has provided role.
139 - *
140 - * @since 2.2.0
141 - *
142 - * @param string $role role.
143 - *
144 - * @return boolean
145 - */
146 - public static function is( string $role ) {
147 - return current_user_can( $role );
148 - }
149 -
150 - /**
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 - * Check user has any role.
172 - *
173 - * @since 2.2.0
174 - * @since 2.6.2 $user_id param added.
175 - *
176 - * @param array $roles roles.
177 - * @param int $user_id user id.
178 - *
179 - * @return boolean
180 - */
181 - public static function has_any_role( array $roles, $user_id = 0 ) {
182 - $user = get_userdata( tutor_utils()->get_user_id( $user_id ) );
183 - if ( empty( $user->roles ) || empty( $roles ) ) {
184 - return false;
185 - }
186 -
187 - foreach ( $roles as $role ) {
188 - if ( in_array( $role, $user->roles, true ) ) {
189 - return true;
190 - }
191 - }
192 -
193 - return false;
194 - }
195 -
196 - /**
197 - * Check user is student.
198 - *
199 - * @since 2.2.0
200 - * @since 2.6.2 $user_id param added.
201 - *
202 - * @param int $user_id user id.
203 - *
204 - * @return boolean
205 - */
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;
209 - }
210 -
211 - /**
212 - * Check user is admin.
213 - *
214 - * @since 2.2.0
215 - * @since 3.2.0 user_id param added.
216 - *
217 - * @param int $user_id user id.
218 - *
219 - * @return boolean
220 - */
221 - public static function is_admin( $user_id = 0 ) {
222 - return user_can( tutor_utils()->get_user_id( $user_id ), self::ADMIN );
223 - }
224 -
225 - /**
226 - * Check current user is instructor.
227 - *
228 - * @since 2.2.0
229 - * @since 3.2.0 user_id param added.
230 - *
231 - * @param int $user_id user id.
232 - * @param bool $is_approved instructor is approved or not.
233 - *
234 - * @return boolean
235 - */
236 - public static function is_instructor( $user_id = 0, $is_approved = true ) {
237 - return tutils()->is_instructor( $user_id, $is_approved );
238 - }
239 -
240 - /**
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 - * Profile layouts
326 - *
327 - * @since 1.0.0
328 - *
329 - * @var array
330 - */
331 25 private $profile_layout = array(
332 26 'pp-circle',
333 27 'pp-rectangle',
334 - 'no-cp',
28 + 'no-cp'
335 29 );
336 30
337 31 /**
338 - * Include edit user template
339 - *
340 - * @since 1.0.0
341 - *
342 - * @param mixed $user user.
343 - *
344 - * @return void
32 + * Show layout selection dashboard in instructor and student setting
345 33 */
346 - public function edit_user_profile( $user ) {
347 - include tutor()->path . 'views/metabox/user-profile-fields.php';
34 + public function tutor_instructor_profile_layout(){
35 + tutor_load_template('public-profile-setting', array('profile_templates'=>$this->profile_layout, 'layout_option_name'=>'instructor'));
348 36 }
37 + public function tutor_student_profile_layout(){
38 + tutor_load_template('public-profile-setting', array('profile_templates'=>$this->profile_layout, 'layout_option_name'=>'student'));
39 + }
349 40
350 - /**
351 - * Delete existing user's photo
352 - *
353 - * @since 1.0.0
354 - *
355 - * @param int $user_id user id.
356 - * @param string $type photo type.
357 - *
358 - * @return void
359 - */
360 - private function delete_existing_user_photo( $user_id, $type ) {
361 - $meta_key = 'cover_photo' == $type ? '_tutor_cover_photo' : '_tutor_profile_photo';
362 - $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 - }
370 - delete_user_meta( $user_id, $meta_key );
41 + public function edit_user_profile($user){
42 + include tutor()->path.'views/metabox/user-profile-fields.php';
371 43 }
372 44
373 - /**
374 - * User photo remove
375 - *
376 - * @since 1.0.0
377 - *
378 - * @return void
379 - */
380 - public function tutor_user_photo_remove() {
381 - tutor_utils()->checking_nonce();
382 - $this->delete_existing_user_photo(
383 - get_current_user_id(),
384 - Input::post( 'photo_type', '' )
385 - );
45 + private function delete_existing_user_photo($user_id, $type){
46 + $meta_key = $type=='cover_photo' ? '_tutor_cover_photo' : '_tutor_profile_photo';
47 + $photo_id = get_user_meta($user_id, $meta_key, true);
48 + is_numeric($photo_id) ? wp_delete_attachment( $photo_id, true) : 0;
49 + delete_user_meta( $user_id, $meta_key);
386 50 }
387 51
388 - /**
389 - * User photo update
390 - *
391 - * @since 1.0.0
392 - *
393 - * @return void
394 - */
395 - public function update_user_photo() {
396 - tutor_utils()->checking_nonce();
52 + public function tutor_user_photo_remove(){
53 + tutils()->checking_nonce();
54 +
55 + $this->delete_existing_user_photo(get_current_user_id(), $_POST['photo_type']);
56 + }
397 57
398 - $user_id = get_current_user_id();
399 - $photo_type = Input::post( 'photo_type', '' );
400 - $meta_key = 'cover_photo' === $photo_type ? '_tutor_cover_photo' : '_tutor_profile_photo';
58 + public function update_user_photo(){
59 + tutils()->checking_nonce();
401 60
61 + $user_id = get_current_user_id();
62 + $meta_key = $_POST['photo_type']=='cover_photo' ? '_tutor_cover_photo' : '_tutor_profile_photo';
63 +
402 64 /**
403 65 * Photo Update from profile
66 + *
404 67 */
405 - $photo = tutor_utils()->array_get( 'photo_file', $_FILES ); //phpcs:ignore -- already sanitized.
406 - $photo_size = tutor_utils()->array_get( 'size', $photo );
407 - $photo_type = tutor_utils()->array_get( 'type', $photo );
68 + $photo = tutils()->array_get('photo_file', $_FILES);
69 + $photo_size = tutils()->array_get('size', $photo);
70 + $photo_type = tutils()->array_get('type', $photo);
408 71
409 - if ( $photo_size && strpos( $photo_type, 'image' ) !== false ) {
72 + if ($photo_size && strpos($photo_type, 'image') !== false) {
410 73 if ( ! function_exists( 'wp_handle_upload' ) ) {
411 - require_once ABSPATH . 'wp-admin/includes/file.php';
74 + require_once( ABSPATH . 'wp-admin/includes/file.php' );
412 75 }
76 +
413 77 $upload_overrides = array( 'test_form' => false );
414 78 $movefile = wp_handle_upload( $photo, $upload_overrides );
415 79
416 80 if ( $movefile && ! isset( $movefile['error'] ) ) {
417 - $file_path = tutor_utils()->array_get( 'file', $movefile );
418 - $file_url = tutor_utils()->array_get( 'url', $movefile );
419 - $mime_type = '';
420 - if ( file_exists( $file_path ) ) {
421 - $image_info = getimagesize( $file_path );
422 - $mime_type = is_array( $image_info ) && count( $image_info ) ? $image_info['mime'] : '';
423 - }
81 + $file_path = tutils()->array_get( 'file', $movefile );
82 + $file_url = tutils()->array_get( 'url', $movefile );
424 83
425 - $media_id = wp_insert_attachment(
426 - array(
427 - 'guid' => $file_path,
428 - 'post_mime_type' => $mime_type,
429 - 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_url ) ),
430 - 'post_content' => '',
431 - 'post_status' => 'inherit',
432 - ),
433 - $file_path,
434 - 0
435 - );
84 + $media_id = wp_insert_attachment( array(
85 + 'guid' => $file_path,
86 + 'post_mime_type' => mime_content_type( $file_path ),
87 + 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_url ) ),
88 + 'post_content' => '',
89 + 'post_status' => 'inherit'
90 + ), $file_path, 0 );
436 91
437 - if ( $media_id ) {
438 - // wp_generate_attachment_metadata() won't work if you do not include this file.
439 - require_once ABSPATH . 'wp-admin/includes/image.php';
92 + if ($media_id) {
93 + // wp_generate_attachment_metadata() won't work if you do not include this file
94 + require_once( ABSPATH . 'wp-admin/includes/image.php' );
440 95
441 - // Generate and save the attachment metas into the database.
96 + // Generate and save the attachment metas into the database
442 97 wp_update_attachment_metadata( $media_id, wp_generate_attachment_metadata( $media_id, $file_path ) );
443 98
444 - // Update it to user profile.
445 - $this->delete_existing_user_photo( $user_id, Input::post( 'photo_type', '' ) );
446 - update_user_meta( $user_id, $meta_key, $media_id );
99 + //Update it to user profile
100 + $this->delete_existing_user_photo($user_id, $_POST['photo_type']);
101 + update_user_meta($user_id, $meta_key, $media_id );
447 102
448 - exit( wp_json_encode( array( 'status' => 'success' ) ) );
103 + exit(json_encode(array('status'=>'success')));
449 104 }
450 105 }
451 106 }
452 107 }
453 108
454 - /**
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 - * Profile update
480 - *
481 - * @since 1.0.0
482 - *
483 - * @param int $user_id user id.
484 - *
485 - * @return void
486 - */
487 - public function profile_update( $user_id ) {
488 - if ( 'tutor_profile_update_by_wp' !== Input::post( 'tutor_action' ) ) {
109 + public function profile_update($user_id){
110 + if (tutils()->array_get('tutor_action', $_POST) !== 'tutor_profile_update_by_wp' ){
489 111 return;
490 112 }
491 113
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 );
114 + $_tutor_profile_job_title = sanitize_text_field(tutor_utils()->avalue_dot('_tutor_profile_job_title', $_POST));
115 + $_tutor_profile_bio = wp_kses_post(tutor_utils()->avalue_dot('_tutor_profile_bio', $_POST));
116 + $_tutor_profile_image = wp_kses_post(tutor_utils()->avalue_dot('_tutor_profile_photo', $_POST));
496 117
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 );
118 + update_user_meta($user_id, '_tutor_profile_job_title', $_tutor_profile_job_title);
119 + update_user_meta($user_id, '_tutor_profile_bio', $_tutor_profile_bio);
120 + update_user_meta($user_id, '_tutor_profile_photo', $_tutor_profile_image);
501 121 }
502 122
503 - /**
504 - * Set user role
505 - *
506 - * @since 1.0.0
507 - *
508 - * @param int $user_id user id.
509 - * @param string $role user role.
510 - * @param array $old_roles old role.
511 - *
512 - * @return void
513 - */
514 - public function set_user_role( $user_id, $role, $old_roles ) {
123 + public function set_user_role($user_id, $role, $old_roles ){
515 124 $instructor_role = tutor()->instructor_role;
516 125
517 - if ( $role === $instructor_role || in_array( $instructor_role, $old_roles ) ) {
518 - tutor_utils()->add_instructor_role( $user_id );
126 + if (in_array($instructor_role, $old_roles)){
127 + // tutor_utils()->remove_instructor_role($user_id);
519 128 }
520 - }
521 129
522 - /**
523 - * Hide notices
524 - *
525 - * @since 1.0.0
526 - *
527 - * @return void
528 - */
529 - public function hide_notices() {
530 - $hide_notice = Input::get( 'tutor-hide-notice', '' );
531 - $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 ) {
535 - tutor_utils()->checking_nonce( 'get' );
536 -
537 - if ( 'enable' === $is_register_enabled ) {
538 - update_option( 'users_can_register', 1 );
539 - } else {
540 - self::$hide_registration_notice = true;
541 - setcookie( 'tutor_notice_hide_registration', 1, time() + MONTH_IN_SECONDS, tutor()->basepath );
542 - }
130 + // if ($role === $instructor_role){
131 + if ($role === $instructor_role || in_array($instructor_role, $old_roles)){
132 + tutor_utils()->add_instructor_role($user_id);
543 133 }
544 134 }
545 -
546 - /**
547 - * Show registration disabled
548 - *
549 - * @since 1.0.0
550 - *
551 - * @return void
552 - */
553 - public function show_registration_disabled() {
554 - if ( self::$hide_registration_notice ||
555 - ( '0' !== get_option( 'users_can_register' ) ) ||
556 - isset( $_COOKIE['tutor_notice_hide_registration'] ) ||
557 - ! current_user_can( 'manage_options' )
558 - ) {
559 - return;
560 - }
561 -
562 - $hide_url = wp_nonce_url( add_query_arg( 'tutor-hide-notice', 'registration' ), tutor()->nonce_action, tutor()->nonce );
563 - ?>
564 - <div class="wrap tutor-user-registration-notice-wrapper">
565 - <div class="tutor-user-registration-notice">
566 - <div>
567 - <img src="<?php echo esc_url( tutor()->url . 'assets/images/icon-info-round.svg' ); ?>"/>
568 - </div>
569 - <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 - ?>
576 - </div>
577 - <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>
581 - <hr/>
582 - <a href="<?php echo esc_url( $hide_url ); ?>">
583 - <?php esc_html_e( 'Dismiss', 'tutor' ); ?>
584 - </a>
585 - </div>
586 - </div>
587 - </div>
588 - <?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 - }
949 -}
135 +}