PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / trunk
Tutor LMS – eLearning and online course solution vtrunk
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 11 months ago Admin.php 2 months ago Ajax.php 9 months ago Announcements.php 1 year ago Assets.php 2 months ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 11 months ago Container.php 11 months ago Course.php 2 months ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 5 months ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 1 year ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 9 months ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Icon.php 8 months ago Input.php 1 year ago Instructor.php 2 months ago Instructors_List.php 2 months ago Lesson.php 2 weeks ago Options_V2.php 7 months ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 10 months ago Question_Answers_List.php 11 months ago Quiz.php 2 weeks ago QuizBuilder.php 2 days ago Quiz_Attempts_List.php 9 months ago RestAPI.php 2 years ago Reviews.php 9 months ago Rewrite_Rules.php 2 years ago Shortcode.php 9 months ago Singleton.php 1 year ago Student.php 2 months ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 9 months ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 3 weeks ago Tutor.php 2 months ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 8 months ago Upgrader.php 9 months ago User.php 4 months ago Utils.php 2 days ago Video_Stream.php 3 years ago WhatsNew.php 9 months ago Withdraw.php 2 days ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 2 days ago
Instructor.php
426 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' ) || ! get_option( 'users_can_register', false ) ) {
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
102 $terms_conditions_link = tutor_utils()->get_toc_page_link();
103 if ( $terms_conditions_link ) {
104 $required_fields['terms_conditions'] = __( 'Please accept the Terms and Conditions to continue', 'tutor' );
105 }
106
107 $validation_errors = array();
108
109 /*
110 * Push into validation_errors
111 * Error registration_errors
112 */
113 $errors = apply_filters( 'registration_errors', new \WP_Error(), '', '' );
114 foreach ( $errors->errors as $key => $value ) {
115 $validation_errors[ $key ] = $value[0];
116 }
117
118 foreach ( $required_fields as $required_key => $required_value ) {
119 if ( empty( $_POST[ $required_key ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
120 $validation_errors[ $required_key ] = $required_value;
121 }
122 }
123
124 if ( ! filter_var( tutor_utils()->input_old( 'email' ), FILTER_VALIDATE_EMAIL ) ) {
125 $validation_errors['email'] = __( 'Valid E-Mail is required', 'tutor' );
126 }
127 if ( tutor_utils()->input_old( 'password' ) !== tutor_utils()->input_old( 'password_confirmation' ) ) {
128 $validation_errors['password_confirmation'] = __( 'Your passwords should match each other. Please recheck.', 'tutor' );
129 }
130
131 if ( count( $validation_errors ) ) {
132 $this->error_msgs = $validation_errors;
133 add_filter( 'tutor_instructor_register_validation_errors', array( $this, 'tutor_instructor_form_validation_errors' ) );
134 return;
135 }
136
137 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
138 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
139 $email = sanitize_text_field( tutor_utils()->input_old( 'email' ) );
140 $user_login = sanitize_text_field( tutor_utils()->input_old( 'user_login' ) );
141 $password = sanitize_text_field( tutor_utils()->input_old( 'password' ) );
142
143 $userdata = array(
144 'user_login' => $user_login,
145 'user_email' => $email,
146 'first_name' => $first_name,
147 'last_name' => $last_name,
148 'user_pass' => $password,
149 );
150
151 global $wpdb;
152 $wpdb->query( 'START TRANSACTION' );
153
154 $user_id = wp_insert_user( $userdata );
155
156 if ( is_wp_error( $user_id ) ) {
157 $this->error_msgs = $user_id->get_error_messages();
158 add_filter( 'tutor_instructor_register_validation_errors', array( $this, 'tutor_instructor_form_validation_errors' ) );
159 return;
160 }
161
162 $is_req_email_verification = apply_filters( 'tutor_require_email_verification', false );
163
164 if ( $is_req_email_verification ) {
165 do_action( 'tutor_send_verification_mail', get_userdata( $user_id ), 'instructor-registration' );
166 $reg_done = apply_filters( 'tutor_registration_done', true );
167 if ( ! $reg_done ) {
168 $wpdb->query( 'ROLLBACK' );
169 return;
170 } else {
171 $wpdb->query( 'COMMIT' );
172 }
173 } else {
174 /**
175 * Tutor Free - regular instructor reg process.
176 */
177 $this->update_instructor_meta( $user_id );
178 $wpdb->query( 'COMMIT' );
179 $user = get_user_by( 'id', $user_id );
180 if ( $user ) {
181 wp_set_current_user( $user_id, $user->user_login );
182 wp_set_auth_cookie( $user_id );
183 do_action( 'tutor_after_instructor_signup', $user_id );
184 }
185 }
186
187 wp_redirect( tutor_utils()->input_old( '_wp_http_referer' ) );
188 die();
189 }
190
191 /**
192 * Get instructor reg validation errors.
193 *
194 * @since 1.0.0
195 * @return string
196 */
197 public function tutor_instructor_form_validation_errors() {
198 return $this->error_msgs;
199 }
200
201 /**
202 * Template Redirect Callback
203 * for instructor applying when a user already logged in
204 *
205 * @since 1.0.0
206 * @return void|null
207 */
208 public function apply_instructor() {
209 // Here tutor_action checking required before nonce checking.
210 if ( 'tutor_apply_instructor' !== Input::post( 'tutor_action' ) ) {
211 return;
212 }
213
214 // Checking nonce.
215 tutor_utils()->checking_nonce();
216
217 $user_id = get_current_user_id();
218 if ( $user_id ) {
219 if ( tutor_utils()->is_instructor() ) {
220 die( esc_html__( 'Already applied for instructor', 'tutor' ) );
221 } else {
222 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
223 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'pending' ) );
224
225 do_action( 'tutor_new_instructor_after', $user_id );
226 }
227 } else {
228 die( esc_html__( 'Permission denied', 'tutor' ) );
229 }
230
231 wp_redirect( tutor_utils()->input_old( '_wp_http_referer' ) );
232 die();
233 }
234
235
236 /**
237 * Add new instructor
238 *
239 * @since 1.0.0
240 * @return void
241 */
242 public function add_new_instructor() {
243 tutor_utils()->checking_nonce();
244
245 // Only admin should be able to add instructor.
246 if ( ! current_user_can( 'manage_options' ) || ! get_option( 'users_can_register', false ) ) {
247 wp_send_json_error();
248 }
249
250 $required_fields = apply_filters(
251 'tutor_instructor_registration_required_fields',
252 array(
253 'first_name' => __( 'First name field is required', 'tutor' ),
254 'last_name' => __( 'Last name field is required', 'tutor' ),
255 'email' => __( 'E-Mail field is required', 'tutor' ),
256 'user_login' => __( 'User Name field is required', 'tutor' ),
257 'password' => __( 'Password field is required', 'tutor' ),
258 'password_confirmation' => __( 'Your passwords should match each other. Please recheck.', 'tutor' ),
259 )
260 );
261
262 $validation_errors = array();
263 foreach ( $required_fields as $required_key => $required_value ) {
264 if ( empty( $_POST[ $required_key ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
265 $validation_errors[ $required_key ] = $required_value;
266 }
267 }
268
269 if ( ! filter_var( tutor_utils()->input_old( 'email' ), FILTER_VALIDATE_EMAIL ) ) {
270 $validation_errors['email'] = __( 'Valid E-Mail is required', 'tutor' );
271 }
272 if ( tutor_utils()->input_old( 'password' ) !== tutor_utils()->input_old( 'password_confirmation' ) ) {
273 $validation_errors['password_confirmation'] = __( 'Your passwords should match each other. Please recheck.', 'tutor' );
274 }
275
276 if ( count( $validation_errors ) ) {
277 wp_send_json_error( array( 'errors' => $validation_errors ) );
278 }
279
280 $first_name = sanitize_text_field( tutor_utils()->input_old( 'first_name' ) );
281 $last_name = sanitize_text_field( tutor_utils()->input_old( 'last_name' ) );
282 $email = sanitize_text_field( tutor_utils()->input_old( 'email' ) );
283 $user_login = sanitize_text_field( tutor_utils()->input_old( 'user_login' ) );
284 $phone_number = sanitize_text_field( tutor_utils()->input_old( 'phone_number' ) );
285 $password = sanitize_text_field( tutor_utils()->input_old( 'password' ) );
286 $tutor_profile_bio = Input::post( 'tutor_profile_bio', '', Input::TYPE_KSES_POST );
287 $tutor_profile_job_title = sanitize_text_field( tutor_utils()->input_old( 'tutor_profile_job_title' ) );
288
289 $userdata = apply_filters(
290 'add_new_instructor_data',
291 array(
292 'user_login' => $user_login,
293 'user_email' => $email,
294 'first_name' => $first_name,
295 'last_name' => $last_name,
296 'role' => tutor()->instructor_role,
297 'user_pass' => $password,
298 )
299 );
300
301 do_action( 'tutor_add_new_instructor_before' );
302
303 $user_id = wp_insert_user( $userdata );
304 if ( ! is_wp_error( $user_id ) ) {
305 update_user_meta( $user_id, 'phone_number', $phone_number );
306 update_user_meta( $user_id, 'description', $tutor_profile_bio );
307 update_user_meta( $user_id, '_tutor_profile_bio', $tutor_profile_bio );
308 update_user_meta( $user_id, '_tutor_profile_job_title', $tutor_profile_job_title );
309 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
310 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'approved' ) );
311
312 do_action( 'tutor_add_new_instructor_after', $user_id );
313
314 wp_send_json_success( array( 'msg' => __( 'Instructor has been added successfully', 'tutor' ) ) );
315 }
316
317 wp_send_json_error( array( 'errors' => $user_id ) );
318 }
319
320 /**
321 * Handle instructor approval action
322 * This function not used maybe, will be removed
323 *
324 * @since 1.0.0
325 * @return void
326 */
327 public function instructor_approval_action() {
328 tutor_utils()->checking_nonce();
329
330 if ( ! current_user_can( 'manage_options' ) ) {
331 wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
332 }
333
334 $instructor_id = Input::post( 'instructor_id', 0, Input::TYPE_INT );
335 $action = Input::post( 'action_name' );
336
337 if ( 'approve' === $action ) {
338 do_action( 'tutor_before_approved_instructor', $instructor_id );
339
340 update_user_meta( $instructor_id, '_tutor_instructor_status', 'approved' );
341 update_user_meta( $instructor_id, '_tutor_instructor_approved', tutor_time() );
342
343 $instructor = new \WP_User( $instructor_id );
344 $instructor->add_role( tutor()->instructor_role );
345
346 // Send E-Mail to this user about instructor approval via hook.
347 do_action( 'tutor_after_approved_instructor', $instructor_id );
348 }
349
350 if ( 'blocked' === $action ) {
351 do_action( 'tutor_before_blocked_instructor', $instructor_id );
352 update_user_meta( $instructor_id, '_tutor_instructor_status', 'blocked' );
353
354 $instructor = new \WP_User( $instructor_id );
355 $instructor->remove_role( tutor()->instructor_role );
356 do_action( 'tutor_after_blocked_instructor', $instructor_id );
357
358 // TODO: send E-Mail to this user about instructor blocked, should via hook.
359 }
360
361 if ( 'remove-instructor' === $action ) {
362 do_action( 'tutor_before_rejected_instructor', $instructor_id );
363
364 $user = new \WP_User( $instructor_id );
365 $user->remove_role( tutor()->instructor_role );
366
367 tutor_utils()->remove_instructor_role( $instructor_id );
368 update_user_meta( $instructor_id, '_is_tutor_instructor_rejected', tutor_time() );
369 update_user_meta( $instructor_id, 'tutor_instructor_show_rejection_message', true );
370
371 // Send E-Mail to this user about instructor rejection via hook.
372 do_action( 'tutor_after_rejected_instructor', $instructor_id );
373 }
374
375 wp_send_json_success();
376 }
377
378 /**
379 * Hide instructor notice
380 *
381 * @since 1.0.0
382 * @return void
383 */
384 public function hide_instructor_notice() {
385 if ( 'hide_instructor_notice' === Input::get( 'tutor_action' ) ) {
386 delete_user_meta( get_current_user_id(), 'tutor_instructor_show_rejection_message' );
387 }
388 }
389
390 /**
391 * Can instructor publish courses directly
392 * Fixed in Gutenberg
393 *
394 * @since 1.5.9
395 * @return void
396 */
397 public function can_publish_tutor_courses() {
398 $can_publish_course = (bool) tutor_utils()->get_option( 'instructor_can_publish_course' );
399
400 $instructor_role = tutor()->instructor_role;
401 $instructor = get_role( $instructor_role );
402
403 if ( $can_publish_course ) {
404 $instructor->add_cap( 'publish_tutor_courses' );
405 } else {
406 $instructor->remove_cap( 'publish_tutor_courses' );
407 }
408 }
409
410 /**
411 * Update instructor meta just after register
412 *
413 * @since 2.1.9
414 *
415 * @param integer $user_id user id.
416 *
417 * @return void
418 */
419 public function update_instructor_meta( int $user_id ) {
420 update_user_meta( $user_id, '_is_tutor_instructor', tutor_time() );
421 update_user_meta( $user_id, '_tutor_instructor_status', apply_filters( 'tutor_initial_instructor_status', 'pending' ) );
422
423 do_action( 'tutor_new_instructor_after', $user_id );
424 }
425 }
426