PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.7.6
Tutor LMS – eLearning and online course solution v2.7.6
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 2 years ago Admin.php 2 years ago Ajax.php 1 year ago Announcements.php 1 year ago Assets.php 2 years ago Backend_Page_Trait.php 3 years ago Course.php 1 year ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 1 year 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 2 years ago Frontend.php 2 years ago Gutenberg.php 3 years ago Input.php 3 years ago Instructor.php 2 years ago Instructors_List.php 1 year ago Lesson.php 1 year ago Options_V2.php 1 year ago Permalink.php 2 years ago Post_types.php 2 years ago Private_Course_Access.php 3 years ago Q_And_A.php 1 year ago Question_Answers_List.php 3 years ago Quiz.php 1 year ago Quiz_Attempts_List.php 1 year ago RestAPI.php 2 years ago Reviews.php 3 years ago Rewrite_Rules.php 2 years ago Shortcode.php 1 year ago Student.php 2 years ago Students_List.php 3 years ago Taxonomies.php 3 years ago Template.php 2 years ago Theme_Compatibility.php 3 years ago Tools.php 3 years ago Tools_V2.php 2 years ago Tutor.php 2 years ago TutorEDD.php 2 years ago Tutor_Base.php 2 years ago Tutor_Setup.php 2 years ago Upgrader.php 2 years ago User.php 2 years ago Utils.php 1 year ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 2 years ago Withdraw_Requests_List.php 3 years ago WooCommerce.php 1 year 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 'password' => __( 'Password field is required', 'tutor' ),
252 'password_confirmation' => __( 'Your passwords should match each other. Please recheck.', 'tutor' ),
253 )
254 );
255
256 $validation_errors = array();
257 foreach ( $required_fields as $required_key => $required_value ) {
258 if ( empty( $_POST[ $required_key ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
259 $validation_errors[ $required_key ] = $required_value;
260 }
261 }
262
263 if ( ! filter_var( tutor_utils()->input_old( 'email' ), FILTER_VALIDATE_EMAIL ) ) {
264 $validation_errors['email'] = __( 'Valid E-Mail is required', 'tutor' );
265 }
266 if ( tutor_utils()->input_old( 'password' ) !== tutor_utils()->input_old( 'password_confirmation' ) ) {
267 $validation_errors['password_confirmation'] = __( 'Your passwords should match each other. Please recheck.', 'tutor' );
268 }
269
270 if ( count( $validation_errors ) ) {
271 wp_send_json_error( array( 'errors' => $validation_errors ) );
272 }
273
274 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
275 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
276 $email = sanitize_text_field( tutor_utils()->input_old( 'email' ) );
277 $user_login = sanitize_text_field( tutor_utils()->input_old( 'user_login' ) );
278 $phone_number = sanitize_text_field( tutor_utils()->input_old( 'phone_number' ) );
279 $password = sanitize_text_field( tutor_utils()->input_old( 'password' ) );
280 $tutor_profile_bio = Input::post( 'tutor_profile_bio', '', Input::TYPE_KSES_POST );
281 $tutor_profile_job_title = sanitize_text_field( tutor_utils()->input_old( 'tutor_profile_job_title' ) );
282
283 $userdata = apply_filters(
284 'add_new_instructor_data',
285 array(
286 'user_login' => $user_login,
287 'user_email' => $email,
288 'first_name' => $first_name,
289 'last_name' => $last_name,
290 'role' => tutor()->instructor_role,
291 'user_pass' => $password,
292 )
293 );
294
295 do_action( 'tutor_add_new_instructor_before' );
296
297 $user_id = wp_insert_user( $userdata );
298 if ( ! is_wp_error( $user_id ) ) {
299 update_user_meta( $user_id, 'phone_number', $phone_number );
300 update_user_meta( $user_id, 'description', $tutor_profile_bio );
301 update_user_meta( $user_id, '_tutor_profile_bio', $tutor_profile_bio );
302 update_user_meta( $user_id, '_tutor_profile_job_title', $tutor_profile_job_title );
303 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
304 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'approved' ) );
305
306 do_action( 'tutor_add_new_instructor_after', $user_id );
307
308 wp_send_json_success( array( 'msg' => __( 'Instructor has been added successfully', 'tutor' ) ) );
309 }
310
311 wp_send_json_error( array( 'errors' => $user_id ) );
312 }
313
314 /**
315 * Handle instructor approval action
316 * This function not used maybe, will be removed
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