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