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