PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.2.1
Tutor LMS – eLearning and online course solution v2.2.1
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 / Instructor.php
tutor / classes Last commit date
Addons.php 3 years ago Admin.php 3 years ago Ajax.php 3 years ago Announcements.php 3 years ago Assets.php 3 years ago Backend_Page_Trait.php 3 years ago Course.php 3 years ago Course_Embed.php 3 years ago Course_Filter.php 3 years ago Course_List.php 3 years ago Course_Settings_Tabs.php 3 years ago Course_Widget.php 3 years ago Custom_Validation.php 3 years ago Dashboard.php 3 years ago FormHandler.php 3 years ago Frontend.php 3 years ago Gutenberg.php 3 years ago Input.php 3 years ago Instructor.php 3 years ago Instructors_List.php 3 years ago Lesson.php 3 years ago Options_V2.php 3 years ago Post_types.php 3 years ago Private_Course_Access.php 3 years ago Q_and_A.php 3 years ago Question_Answers_List.php 3 years ago Quiz.php 3 years ago Quiz_Attempts_List.php 3 years ago RestAPI.php 3 years ago Reviews.php 3 years ago Rewrite_Rules.php 3 years ago Shortcode.php 3 years ago Student.php 3 years ago Students_List.php 3 years ago Taxonomies.php 3 years ago Template.php 3 years ago Theme_Compatibility.php 3 years ago Tools.php 3 years ago Tools_V2.php 3 years ago Tutor.php 3 years ago TutorEDD.php 3 years ago Tutor_Base.php 3 years ago Tutor_Setup.php 3 years ago Upgrader.php 3 years ago User.php 3 years ago Utils.php 3 years ago Video_Stream.php 3 years ago Withdraw.php 3 years ago Withdraw_Requests_List.php 3 years ago WooCommerce.php 3 years ago
Instructor.php
416 lines
1 <?php
2 /**
3 * Manage Instructor
4 *
5 * @package Tutor
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Instructor class
19 *
20 * @since 1.0.0
21 */
22 class Instructor {
23
24 /**
25 * Error message
26 *
27 * @var string
28 */
29 protected $error_msgs = '';
30
31 /**
32 * Constructor
33 *
34 * @since 1.0.0
35 * @return void
36 */
37 public function __construct( $register_hook = true ) {
38 if ( ! $register_hook ) {
39 return;
40 }
41 add_action( 'template_redirect', array( $this, 'register_instructor' ) );
42 add_action( 'template_redirect', array( $this, 'apply_instructor' ) );
43
44 // Add instructor from admin panel.
45 add_action( 'wp_ajax_tutor_add_instructor', array( $this, 'add_new_instructor' ) );
46
47 /**
48 * Instructor Approval
49 * Block Unblock
50 *
51 * @since 1.5.3
52 */
53 add_action( 'wp_ajax_instructor_approval_action', array( $this, 'instructor_approval_action' ) );
54
55 /**
56 * Check if instructor can publish courses
57 *
58 * @since 1.5.9
59 */
60 add_action( 'tutor_option_save_after', array( $this, 'can_publish_tutor_courses' ) );
61
62 /**
63 * Hide instructor rejection message
64 *
65 * @since 1.9.2
66 */
67 add_action( 'wp_loaded', array( $this, 'hide_instructor_notice' ) );
68 }
69
70 /**
71 * Template Redirect Callback
72 * For Register new user and mark him as instructor
73 *
74 * @since 1.0.0
75 * @return void|null
76 */
77 public function register_instructor() {
78 // Here tutor_action checking required before nonce checking.
79 if ( 'tutor_register_instructor' !== Input::post( 'tutor_action' ) ) {
80 return;
81 }
82
83 // Checking nonce.
84 tutor_utils()->checking_nonce();
85
86 $required_fields = apply_filters(
87 'tutor_instructor_registration_required_fields',
88 array(
89 'first_name' => __( 'First name field is required', 'tutor' ),
90 'last_name' => __( 'Last name field is required', 'tutor' ),
91 'email' => __( 'E-Mail field is required', 'tutor' ),
92 'user_login' => __( 'User Name field is required', 'tutor' ),
93 'password' => __( 'Password field is required', 'tutor' ),
94 'password_confirmation' => __( 'Password Confirmation field is required', 'tutor' ),
95 )
96 );
97
98 $validation_errors = array();
99
100 /*
101 * Push into validation_errors
102 * Error registration_errors
103 */
104 $errors = apply_filters( 'registration_errors', new \WP_Error(), '', '' );
105 foreach ( $errors->errors as $key => $value ) {
106 $validation_errors[ $key ] = $value[0];
107 }
108
109 foreach ( $required_fields as $required_key => $required_value ) {
110 if ( empty( $_POST[ $required_key ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
111 $validation_errors[ $required_key ] = $required_value;
112 }
113 }
114
115 if ( ! filter_var( tutor_utils()->input_old( 'email' ), FILTER_VALIDATE_EMAIL ) ) {
116 $validation_errors['email'] = __( 'Valid E-Mail is required', 'tutor' );
117 }
118 if ( tutor_utils()->input_old( 'password' ) !== tutor_utils()->input_old( 'password_confirmation' ) ) {
119 $validation_errors['password_confirmation'] = __( 'Your passwords should match each other. Please recheck.', 'tutor' );
120 }
121
122 if ( count( $validation_errors ) ) {
123 $this->error_msgs = $validation_errors;
124 add_filter( 'tutor_instructor_register_validation_errors', array( $this, 'tutor_instructor_form_validation_errors' ) );
125 return;
126 }
127
128 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
129 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
130 $email = sanitize_text_field( tutor_utils()->input_old( 'email' ) );
131 $user_login = sanitize_text_field( tutor_utils()->input_old( 'user_login' ) );
132 $password = sanitize_text_field( tutor_utils()->input_old( 'password' ) );
133
134 $userdata = array(
135 'user_login' => $user_login,
136 'user_email' => $email,
137 'first_name' => $first_name,
138 'last_name' => $last_name,
139 'user_pass' => $password,
140 );
141
142 global $wpdb;
143 $wpdb->query( 'START TRANSACTION' );
144
145 $user_id = wp_insert_user( $userdata );
146
147 if ( is_wp_error( $user_id ) ) {
148 $this->error_msgs = $user_id->get_error_messages();
149 add_filter( 'tutor_instructor_register_validation_errors', array( $this, 'tutor_instructor_form_validation_errors' ) );
150 return;
151 }
152
153 $is_req_email_verification = apply_filters( 'tutor_require_email_verification', false );
154
155 if ( $is_req_email_verification ) {
156 do_action( 'tutor_send_verification_mail', get_userdata( $user_id ), 'instructor-registration' );
157 $reg_done = apply_filters( 'tutor_registration_done', true );
158 if ( ! $reg_done ) {
159 $wpdb->query( 'ROLLBACK' );
160 return;
161 } else {
162 $wpdb->query( 'COMMIT' );
163 }
164 } else {
165 /**
166 * Tutor Free - regular instructor reg process.
167 */
168 $this->update_instructor_meta( $user_id );
169 $wpdb->query( 'COMMIT' );
170 $user = get_user_by( 'id', $user_id );
171 if ( $user ) {
172 wp_set_current_user( $user_id, $user->user_login );
173 wp_set_auth_cookie( $user_id );
174 }
175 }
176
177 wp_redirect( tutor_utils()->input_old( '_wp_http_referer' ) );
178 die();
179 }
180
181 /**
182 * Get instructor reg validation errors.
183 *
184 * @since 1.0.0
185 * @return string
186 */
187 public function tutor_instructor_form_validation_errors() {
188 return $this->error_msgs;
189 }
190
191 /**
192 * Template Redirect Callback
193 * for instructor applying when a user already logged in
194 *
195 * @since 1.0.0
196 * @return void|null
197 */
198 public function apply_instructor() {
199 // Here tutor_action checking required before nonce checking.
200 if ( 'tutor_apply_instructor' !== Input::post( 'tutor_action' ) ) {
201 return;
202 }
203
204 // Checking nonce.
205 tutor_utils()->checking_nonce();
206
207 $user_id = get_current_user_id();
208 if ( $user_id ) {
209 if ( tutor_utils()->is_instructor() ) {
210 die( esc_html__( 'Already applied for instructor', 'tutor' ) );
211 } else {
212 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
213 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'pending' ) );
214
215 do_action( 'tutor_new_instructor_after', $user_id );
216 }
217 } else {
218 die( esc_html__( 'Permission denied', 'tutor' ) );
219 }
220
221 wp_redirect( tutor_utils()->input_old( '_wp_http_referer' ) );
222 die();
223 }
224
225
226 /**
227 * Add new instructor
228 *
229 * @since 1.0.0
230 * @return void
231 */
232 public function add_new_instructor() {
233 tutor_utils()->checking_nonce();
234
235 // Only admin should be able to add instructor.
236 if ( ! current_user_can( 'manage_options' ) || ! get_option( 'users_can_register', false ) ) {
237 wp_send_json_error();
238 }
239
240 $required_fields = apply_filters(
241 'tutor_instructor_registration_required_fields',
242 array(
243 'first_name' => __( 'First name field is required', 'tutor' ),
244 'last_name' => __( 'Last name field is required', 'tutor' ),
245 'email' => __( 'E-Mail field is required', 'tutor' ),
246 'user_login' => __( 'User Name field is required', 'tutor' ),
247 'phone_number' => __( 'Phone Number field is required', 'tutor' ),
248 'password' => __( 'Password field is required', 'tutor' ),
249 'password_confirmation' => __( 'Your passwords should match each other. Please recheck.', 'tutor' ),
250 )
251 );
252
253 $validation_errors = array();
254 foreach ( $required_fields as $required_key => $required_value ) {
255 if ( empty( $_POST[ $required_key ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
256 $validation_errors[ $required_key ] = $required_value;
257 }
258 }
259
260 if ( ! filter_var( tutor_utils()->input_old( 'email' ), FILTER_VALIDATE_EMAIL ) ) {
261 $validation_errors['email'] = __( 'Valid E-Mail is required', 'tutor' );
262 }
263 if ( tutor_utils()->input_old( 'password' ) !== tutor_utils()->input_old( 'password_confirmation' ) ) {
264 $validation_errors['password_confirmation'] = __( 'Your passwords should match each other. Please recheck.', 'tutor' );
265 }
266
267 if ( count( $validation_errors ) ) {
268 wp_send_json_error( array( 'errors' => $validation_errors ) );
269 }
270
271 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
272 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
273 $email = sanitize_text_field( tutor_utils()->input_old( 'email' ) );
274 $user_login = sanitize_text_field( tutor_utils()->input_old( 'user_login' ) );
275 $phone_number = sanitize_text_field( tutor_utils()->input_old( 'phone_number' ) );
276 $password = sanitize_text_field( tutor_utils()->input_old( 'password' ) );
277 $tutor_profile_bio = wp_kses_post( tutor_utils()->input_old( 'tutor_profile_bio' ) );
278 $tutor_profile_job_title = sanitize_text_field( tutor_utils()->input_old( 'tutor_profile_job_title' ) );
279
280 $userdata = apply_filters(
281 'add_new_instructor_data',
282 array(
283 'user_login' => $user_login,
284 'user_email' => $email,
285 'first_name' => $first_name,
286 'last_name' => $last_name,
287 'role' => tutor()->instructor_role,
288 'user_pass' => $password,
289 )
290 );
291
292 do_action( 'tutor_add_new_instructor_before' );
293
294 $user_id = wp_insert_user( $userdata );
295 if ( ! is_wp_error( $user_id ) ) {
296 update_user_meta( $user_id, 'phone_number', $phone_number );
297 update_user_meta( $user_id, 'description', $tutor_profile_bio );
298 update_user_meta( $user_id, '_tutor_profile_bio', $tutor_profile_bio );
299 update_user_meta( $user_id, '_tutor_profile_job_title', $tutor_profile_job_title );
300 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
301 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'approved' ) );
302
303 do_action( 'tutor_add_new_instructor_after', $user_id );
304
305 wp_send_json_success( array( 'msg' => __( 'Instructor has been added successfully', 'tutor' ) ) );
306 }
307
308 wp_send_json_error( array( 'errors' => $user_id ) );
309 }
310
311 /**
312 * Handle instructor approval action
313 *
314 * @since 1.0.0
315 * @return void
316 */
317 public function instructor_approval_action() {
318 tutor_utils()->checking_nonce();
319
320 if ( ! current_user_can( 'manage_options' ) ) {
321 wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
322 }
323
324 $instructor_id = Input::post( 'instructor_id', 0, Input::TYPE_INT );
325 $action = Input::post( 'action_name' );
326
327 if ( 'approve' === $action ) {
328 do_action( 'tutor_before_approved_instructor', $instructor_id );
329
330 update_user_meta( $instructor_id, '_tutor_instructor_status', 'approved' );
331 update_user_meta( $instructor_id, '_tutor_instructor_approved', tutor_time() );
332
333 $instructor = new \WP_User( $instructor_id );
334 $instructor->add_role( tutor()->instructor_role );
335
336 // Send E-Mail to this user about instructor approval via hook.
337 do_action( 'tutor_after_approved_instructor', $instructor_id );
338 }
339
340 if ( 'blocked' === $action ) {
341 do_action( 'tutor_before_blocked_instructor', $instructor_id );
342 update_user_meta( $instructor_id, '_tutor_instructor_status', 'blocked' );
343
344 $instructor = new \WP_User( $instructor_id );
345 $instructor->remove_role( tutor()->instructor_role );
346 do_action( 'tutor_after_blocked_instructor', $instructor_id );
347
348 // TODO: send E-Mail to this user about instructor blocked, should via hook.
349 }
350
351 if ( 'remove-instructor' === $action ) {
352 do_action( 'tutor_before_rejected_instructor', $instructor_id );
353
354 $user = new \WP_User( $instructor_id );
355 $user->remove_role( tutor()->instructor_role );
356
357 tutor_utils()->remove_instructor_role( $instructor_id );
358 update_user_meta( $instructor_id, '_is_tutor_instructor_rejected', tutor_time() );
359 update_user_meta( $instructor_id, 'tutor_instructor_show_rejection_message', true );
360
361 // Send E-Mail to this user about instructor rejection via hook.
362 do_action( 'tutor_after_rejected_instructor', $instructor_id );
363 }
364
365 wp_send_json_success();
366 }
367
368 /**
369 * Hide instructor notice
370 *
371 * @since 1.0.0
372 * @return void
373 */
374 public function hide_instructor_notice() {
375 if ( 'hide_instructor_notice' === Input::get( 'tutor_action' ) ) {
376 delete_user_meta( get_current_user_id(), 'tutor_instructor_show_rejection_message' );
377 }
378 }
379
380 /**
381 * Can instructor publish courses directly
382 * Fixed in Gutenberg
383 *
384 * @since 1.5.9
385 * @return void
386 */
387 public function can_publish_tutor_courses() {
388 $can_publish_course = (bool) tutor_utils()->get_option( 'instructor_can_publish_course' );
389
390 $instructor_role = tutor()->instructor_role;
391 $instructor = get_role( $instructor_role );
392
393 if ( $can_publish_course ) {
394 $instructor->add_cap( 'publish_tutor_courses' );
395 } else {
396 $instructor->remove_cap( 'publish_tutor_courses' );
397 }
398 }
399
400 /**
401 * Update instructor meta just after register
402 *
403 * @since 2.1.9
404 *
405 * @param integer $user_id user id.
406 *
407 * @return void
408 */
409 public function update_instructor_meta( int $user_id ) {
410 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
411 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'pending' ) );
412
413 do_action( 'tutor_new_instructor_after', $user_id );
414 }
415 }
416