PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.0
Tutor LMS – eLearning and online course solution v4.0.0
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 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 / Student.php
tutor / classes Last commit date
Addons.php 16 hours ago Admin.php 16 hours ago Ajax.php 16 hours ago Announcements.php 16 hours ago Assets.php 16 hours ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 16 hours ago Container.php 11 months ago Course.php 16 hours ago Course_Embed.php 3 years ago Course_Filter.php 16 hours ago Course_List.php 16 hours ago Course_Settings_Tabs.php 16 hours ago Course_Widget.php 1 year ago Custom_Validation.php 16 hours ago Dashboard.php 16 hours ago Earnings.php 9 months ago FormHandler.php 16 hours ago Frontend.php 16 hours ago Gutenberg.php 1 year ago Icon.php 16 hours ago Input.php 16 hours ago Instructor.php 16 hours ago Instructors_List.php 16 hours ago Lesson.php 16 hours ago Options_V2.php 16 hours ago Permalink.php 16 hours ago Post_types.php 1 day ago Private_Course_Access.php 16 hours ago Q_And_A.php 16 hours ago Question_Answers_List.php 11 months ago Quiz.php 16 hours ago QuizBuilder.php 16 hours ago Quiz_Attempts_List.php 16 hours ago RestAPI.php 2 years ago Reviews.php 16 hours ago Rewrite_Rules.php 2 years ago SampleCourse.php 16 hours ago Shortcode.php 16 hours ago Singleton.php 1 year ago Student.php 16 hours ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 16 hours ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 4 weeks ago Tutor.php 16 hours ago TutorEDD.php 16 hours ago Tutor_Base.php 2 years ago Tutor_Setup.php 16 hours ago Upgrader.php 16 hours ago User.php 16 hours ago UserPreference.php 16 hours ago Utils.php 16 hours ago Video_Stream.php 3 years ago WhatsNew.php 10 months ago Withdraw.php 16 hours ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 16 hours ago
Student.php
409 lines
1 <?php
2 /**
3 * Class Student
4 *
5 * @package Tutor\Student
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 use Tutor\GDPR\Controllers\LegalConsent;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Manage students
21 *
22 * @since 1.0.0
23 */
24 class Student {
25
26 /**
27 * Bagged error messages
28 *
29 * @since 1.0.0
30 *
31 * @var $error_msgs
32 */
33 protected $error_msgs = '';
34
35 /**
36 * Handle Hooks
37 *
38 * @since 1.0.0
39 */
40 public function __construct() {
41 add_action( 'template_redirect', array( $this, 'register_student' ) );
42 add_filter( 'get_avatar_url', array( $this, 'filter_avatar' ), 10, 3 );
43 add_action( 'wp_ajax_tutor_social_profile', array( $this, 'tutor_social_profile' ) );
44 add_action( 'wp_ajax_tutor_profile_password_reset', array( $this, 'tutor_reset_password' ) );
45 add_action( 'wp_ajax_tutor_update_profile', array( $this, 'update_profile' ) );
46 }
47
48 /**
49 * Register new user and mark him as student
50 *
51 * @since 1.0.0
52 *
53 * @return void
54 */
55 public function register_student() {
56 if ( 'tutor_register_student' !== Input::post( 'tutor_action', '' ) || ! get_option( 'users_can_register', false ) ) {
57 // Action must be register, and registration must be enabled in dashboard.
58 return;
59 }
60
61 // Checking nonce.
62 tutor_utils()->checking_nonce();
63 $required_fields = apply_filters(
64 'tutor_student_registration_required_fields',
65 array(
66 'first_name' => __( 'First name field is required', 'tutor' ),
67 'last_name' => __( 'Last name field is required', 'tutor' ),
68 'email' => __( 'E-Mail field is required', 'tutor' ),
69 'user_login' => __( 'User Name field is required', 'tutor' ),
70 'password' => __( 'Password field is required', 'tutor' ),
71 'password_confirmation' => __( 'Password Confirmation field is required', 'tutor' ),
72 )
73 );
74
75 $validation_errors = array();
76
77 // Registration error push into validation_errors.
78 $errors = apply_filters( 'registration_errors', new \WP_Error(), '', '' );
79 foreach ( $errors->errors as $key => $value ) {
80 $validation_errors[ $key ] = $value[0];
81 }
82
83 foreach ( $required_fields as $required_key => $required_value ) {
84 if ( empty( Input::post( $required_key, '' ) ) ) {
85 $validation_errors[ $required_key ] = $required_value;
86 }
87 }
88
89 // @since 4.0.0 legal consent added.
90 $validate_consent = LegalConsent::validate_consent( LegalConsent::DISPLAY_ON_STD_REG, $_POST );
91 if ( is_wp_error( $validate_consent ) ) {
92 $validation_errors[ $validate_consent->get_error_code() ] = $validate_consent->get_error_message();
93 }
94
95 if ( ! filter_var( tutor_utils()->input_old( 'email' ), FILTER_VALIDATE_EMAIL ) ) {
96 $validation_errors['email'] = __( 'Valid E-Mail is required', 'tutor' );
97 }
98
99 if ( tutor_utils()->input_old( 'password' ) !== tutor_utils()->input_old( 'password_confirmation' ) ) {
100 $validation_errors['password_confirmation'] = __( 'Your passwords should match each other. Please recheck.', 'tutor' );
101 }
102
103 if ( count( $validation_errors ) ) {
104 $this->error_msgs = $validation_errors;
105 add_filter( 'tutor_student_register_validation_errors', array( $this, 'tutor_student_form_validation_errors' ) );
106 return;
107 }
108
109 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
110 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
111 $email = sanitize_text_field( tutor_utils()->input_old( 'email' ) );
112 $user_login = sanitize_text_field( tutor_utils()->input_old( 'user_login' ) );
113 $password = sanitize_text_field( tutor_utils()->input_old( 'password' ) );
114 $userdata = array(
115 'user_login' => $user_login,
116 'user_email' => $email,
117 'first_name' => $first_name,
118 'last_name' => $last_name,
119 'user_pass' => $password,
120 );
121
122 global $wpdb;
123 $wpdb->query( 'START TRANSACTION' );
124 $user_id = wp_insert_user( $userdata );
125 $enroll_attempt = Input::post( 'tutor_course_enroll_attempt', '' );
126 if ( is_wp_error( $user_id ) ) {
127 $this->error_msgs = $user_id->get_error_messages();
128 add_filter( 'tutor_student_register_validation_errors', array( $this, 'tutor_student_form_validation_errors' ) );
129 return;
130 }
131
132 $user = get_user_by( 'id', $user_id );
133
134 $redirect_url = '';
135
136 $is_req_email_verification = apply_filters( 'tutor_require_email_verification', false );
137 if ( $is_req_email_verification ) {
138 $redirect_url = tutor_utils()->student_register_url();
139
140 do_action( 'tutor_send_verification_mail', $user, $enroll_attempt );
141 $reg_done = apply_filters( 'tutor_registration_done', true );
142 if ( ! $reg_done ) {
143 $wpdb->query( 'ROLLBACK' );
144 return;
145 } else {
146 $wpdb->query( 'COMMIT' );
147
148 }
149 } else {
150 /**
151 * Tutor Free - reqular student reg process.
152 */
153 $wpdb->query( 'COMMIT' );
154
155 wp_set_current_user( $user_id, $user->user_login );
156 wp_set_auth_cookie( $user_id );
157 do_action( 'tutor_after_student_signup', $user_id );
158
159 // since 1.9.8 do enroll if guest attempt to enroll.
160 if ( ! empty( $enroll_attempt ) ) {
161 do_action( 'tutor_do_enroll_after_login_if_attempt', $enroll_attempt, $user_id );
162 }
163
164 // Redirect page.
165 $redirect_url = tutor_utils()->array_get( 'redirect_to', $_REQUEST ); //phpcs:ignore
166 if ( ! $redirect_url ) {
167 $redirect_url = tutor_utils()->tutor_dashboard_url();
168 }
169 }
170
171 do_action( 'tutor_new_user_registered', $user, $validate_consent );
172 wp_safe_redirect( apply_filters( 'tutor_student_register_redirect_url', tutor_utils()->get_nocache_url( $redirect_url ), $user ) );
173 die();
174 }
175
176 /**
177 * Get validation error messages
178 *
179 * @since 1.0.0
180 *
181 * @return mixed error messages
182 */
183 public function tutor_student_form_validation_errors() {
184 return $this->error_msgs;
185 }
186
187 /**
188 * Update profile
189 *
190 * @since 1.0.0
191 *
192 * @return void send wp_json response
193 */
194 public function update_profile() {
195 // Checking nonce.
196 tutor_utils()->checking_nonce();
197
198 $user_id = get_current_user_id();
199 do_action( 'tutor_profile_update_before', $user_id );
200
201 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
202 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
203 $phone_number = sanitize_text_field( tutor_utils()->input_old( 'phone_number' ) );
204 $tutor_profile_bio = wp_kses( Input::post( 'tutor_profile_bio', '', Input::TYPE_KSES_POST ), tutor_utils()->allowed_profile_bio_tags() );
205 $tutor_profile_job_title = sanitize_text_field( tutor_utils()->input_old( 'tutor_profile_job_title' ) );
206 $timezone = Input::post( 'timezone', '' );
207
208 $display_name = sanitize_text_field( tutor_utils()->input_old( 'display_name' ) );
209
210 $userdata = array(
211 'ID' => $user_id,
212 'first_name' => $first_name,
213 'last_name' => $last_name,
214 'display_name' => $display_name,
215 );
216
217 $user_id = wp_update_user( $userdata );
218
219 if ( ! is_wp_error( $user_id ) ) {
220 update_user_meta( $user_id, User::PHONE_NUMBER_META, $phone_number );
221 update_user_meta( $user_id, User::PROFILE_BIO_META, $tutor_profile_bio );
222 update_user_meta( $user_id, User::PROFILE_JOB_TITLE_META, $tutor_profile_job_title );
223 update_user_meta( $user_id, User::TIMEZONE_META, $timezone );
224 }
225
226 do_action( 'tutor_profile_update_after', $user_id );
227
228 wp_send_json_success( array( 'message' => __( 'Profile Updated', 'tutor' ) ) );
229 }
230
231 /**
232 * Filter Avatar, Change avatar URL with Tutor User Photo
233 *
234 * @since 1.0.0
235 *
236 * @param string $url url.
237 * @param mixed $id_or_email id or email.
238 * @param array $args extra args.
239 *
240 * @return false|string
241 */
242 public function filter_avatar( $url, $id_or_email, $args ) {
243
244 $finder = false;
245 $is_id = is_numeric( $id_or_email );
246
247 if ( $is_id ) {
248 $finder = absint( $id_or_email );
249 } elseif ( is_string( $id_or_email ) ) {
250 $finder = $id_or_email;
251 } elseif ( $id_or_email instanceof \WP_User ) {
252 // User Object.
253 $finder = $id_or_email->ID;
254 } elseif ( $id_or_email instanceof \WP_Post ) {
255 // Post Object.
256 $finder = (int) $id_or_email->post_author;
257 } elseif ( $id_or_email instanceof \WP_Comment ) {
258 return $url;
259 }
260
261 if ( ! $finder ) {
262 return $url;
263 }
264
265 $user = get_user_by( $is_id ? 'ID' : 'email', $finder );
266
267 if ( $user ) {
268 $profile_photo = get_user_meta( $user->ID, '_tutor_profile_photo', true );
269 if ( $profile_photo ) {
270 $size = isset( $args['size'] ) ? $args['size'] : 'thumbnail';
271 $url = wp_get_attachment_image_url( $profile_photo, $size );
272 }
273 }
274 return $url;
275 }
276
277 /**
278 * Password Rest
279 *
280 * @since 1.0.0
281 *
282 * @return void send wp_json response
283 */
284 public function tutor_reset_password() {
285 // Checking nonce.
286 tutor_utils()->checking_nonce();
287
288 $user = wp_get_current_user();
289
290 $previous_password = Input::post( 'previous_password', '' );
291 $new_password = Input::post( 'new_password', '' );
292 $confirm_new_password = Input::post( 'confirm_new_password', '' );
293
294 $previous_password_checked = wp_check_password( $previous_password, $user->user_pass, $user->ID );
295
296 $validation_errors = array();
297 if ( ! $previous_password_checked ) {
298 $validation_errors['incorrect_previous_password'] = __( 'Incorrect Previous Password', 'tutor' );
299 }
300 if ( empty( $new_password ) ) {
301 $validation_errors['new_password_required'] = __( 'New Password Required', 'tutor' );
302 }
303 if ( empty( $confirm_new_password ) ) {
304 $validation_errors['confirm_password_required'] = __( 'Confirm Password Required', 'tutor' );
305 }
306 if ( $new_password !== $confirm_new_password ) {
307 $validation_errors['password_not_matched'] = __( 'New password and confirm password does not matched', 'tutor' );
308 }
309
310 if ( $previous_password_checked && ! empty( $new_password ) && $new_password === $confirm_new_password ) {
311 wp_set_password( $new_password, $user->ID );
312 wp_send_json_success( array( 'message' => __( 'Password Changed', 'tutor' ) ) );
313 }
314
315 $first_message = count( $validation_errors ) ? $validation_errors[ array_keys( $validation_errors )[0] ] : __( 'Something went wrong!', 'tutor' );
316 wp_send_json_error( array( 'message' => $first_message ) );
317 }
318
319 /**
320 * Handle social links
321 *
322 * @since 2.0.0
323 *
324 * @return void
325 */
326 public function tutor_social_profile() {
327 tutor_utils()->checking_nonce();
328
329 $user_id = get_current_user_id();
330 $tutor_user_social = tutor_utils()->tutor_user_social_icons();
331
332 foreach ( $tutor_user_social as $key => $social ) {
333 $user_social_value = sanitize_text_field( tutor_utils()->input_old( $key ) );
334 if ( '' !== $user_social_value ) {
335 update_user_meta( $user_id, $key, $user_social_value );
336 } else {
337 delete_user_meta( $user_id, $key );
338 }
339 }
340
341 wp_send_json_success( array( 'message' => __( 'Social Profile Updated', 'tutor' ) ) );
342 die();
343 }
344
345 /**
346 * Get courses tab configuration for student dashboard
347 *
348 * Generates the tab structure for displaying student courses with dropdown options
349 * for enrolled, active, and completed courses including counts and navigation URLs.
350 *
351 * @since 4.0.0
352 *
353 * @param string $active_tab The currently active tab identifier.
354 * @param array $post_type_args Query arguments for post type filtering.
355 * @param int $enrolled_course_count Number of enrolled courses.
356 * @param int $active_course_count Number of active courses.
357 * @param int $completed_course_count Number of completed courses.
358 *
359 * @return array Array containing tab configuration with dropdown options
360 */
361 public function get_courses_tab( $active_tab, $post_type_args, $enrolled_course_count, $active_course_count, $completed_course_count ) {
362 $courses_tab = array(
363 array(
364 'type' => 'dropdown',
365 'active' => ( ( 'courses' === $active_tab ) || ( 'courses/active-courses' === $active_tab ) || ( 'courses/completed-courses' === $active_tab ) ) ? true : false,
366 'options' => array(
367 array(
368 'label' => __( 'Enrolled', 'tutor' ),
369 'icon' => Icon::ENROLLED,
370 'url' => esc_url( add_query_arg( $post_type_args, tutor_utils()->get_tutor_dashboard_page_permalink( 'courses' ) ) ),
371 'active' => 'courses' === $active_tab ? true : false,
372 'count' => $enrolled_course_count,
373 ),
374 array(
375 'label' => __( 'Active', 'tutor' ),
376 'icon' => Icon::PLAY_LINE_2,
377 'url' => esc_url( add_query_arg( $post_type_args, tutor_utils()->get_tutor_dashboard_page_permalink( 'courses/active-courses' ) ) ),
378 'active' => 'courses/active-courses' === $active_tab ? true : false,
379 'count' => $active_course_count,
380 ),
381 array(
382 'label' => __( 'Complete', 'tutor' ),
383 'icon' => Icon::COMPLETED_CIRCLE,
384 'url' => esc_url( add_query_arg( $post_type_args, tutor_utils()->get_tutor_dashboard_page_permalink( 'courses/completed-courses' ) ) ),
385 'active' => 'courses/completed-courses' === $active_tab ? true : false,
386 'count' => $completed_course_count,
387 ),
388 ),
389 ),
390 array(
391 'type' => 'link',
392 'label' => __( 'Wishlist', 'tutor' ),
393 'icon' => Icon::WISHLIST,
394 'url' => esc_url( tutor_utils()->tutor_dashboard_url( 'courses/wishlist' ) ),
395 'active' => 'courses/wishlist' === $active_tab ? true : false,
396 ),
397 array(
398 'type' => 'link',
399 'label' => __( 'Quiz Attempts', 'tutor' ),
400 'icon' => Icon::QUIZ_2,
401 'url' => esc_url( tutor_utils()->tutor_dashboard_url( 'courses/my-quiz-attempts' ) ),
402 'active' => 'courses/my-quiz-attempts' === $active_tab ? true : false,
403 ),
404 );
405
406 return $courses_tab;
407 }
408 }
409