PluginProbe
Awesome Support – WordPress HelpDesk & Support Plugin / trunk
Awesome Support – WordPress HelpDesk & Support Plugin vtrunk
6.4.0 trunk 3.0.0 3.0.1 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 All 95 releases
awesome-support / includes / functions-user.php

functions-user.php in Awesome Support – WordPress HelpDesk & Support Plugin trunk, at includes/functions-user.php

1,889 lines 49.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 add_action( 'wpas_do_register', 'wpas_register_account' );
3 /**
4 * Register user account.
5 *
6 * This function is hooked onto wpas_do_register so that the registration process can be triggered
7 * when the registration form is submitted.
8 *
9 * @param array $data User data
10 *
11 * @since 1.0.0
12 * @return void
13 */
14 function wpas_register_account( $data ) {
15
16 // Get the redirect URL
17 $redirect_to = home_url();
18
19 if ( isset( $data['redirect_to'] ) ) {
20 $redirect_to = wp_sanitize_redirect( $data['redirect_to'] ); // If a redirect URL is specified we use it
21 } else {
22
23 global $post;
24
25 // Otherwise we try to get the URL of the originating page
26 if ( isset( $post ) && $post instanceof WP_Post ) {
27 $redirect_to = wp_sanitize_redirect( get_permalink( $post->ID ) );
28 }
29
30 }
31
32 /* Make sure registrations are open */
33 $registration = wpas_get_option( 'allow_registrations', 'allow' );
34
35 if ( 'allow' !== $registration && 'moderated' !== $registration ) {
36 wpas_add_error( 'registration_not_allowed', __( 'Registrations are currently not allowed.', 'awesome-support' ) );
37 wp_safe_redirect( $redirect_to );
38 exit;
39 }
40
41 // Prepare user data
42 $user = array(
43 'email' => isset( $data['wpas_email'] ) ? $data['wpas_email'] : '',
44 'first_name' => isset( $data['wpas_first_name'] ) ? $data['wpas_first_name'] : '',
45 'last_name' => isset( $data['wpas_last_name'] ) ? $data['wpas_last_name'] : '',
46 'pwd' => isset( $data['wpas_password'] ) ? $data['wpas_password'] : '',
47 );
48
49 /**
50 * wpas_pre_register_account hook
51 *
52 * This hook is triggered all the time
53 * even if the checks don't pass.
54 *
55 * @since 3.0.1
56 */
57 do_action( 'wpas_pre_register_account', $user, $redirect_to, $data );
58
59 // translators: %s is the name of the checkbox that needs to be checked.
60 $x_content = __( 'You must check the <b>%s</b> box in order to register a support account on this site.', 'awesome-support' );
61
62 if ( wpas_get_option( 'terms_conditions', false ) && ( ! isset( $data['wpas_terms'] ) || $data['wpas_terms'][0] != "1" ) ) {
63 wpas_add_error( 'accept_terms_conditions', esc_html__( 'You did not accept the terms and conditions.', 'awesome-support' ) );
64 wp_safe_redirect( $redirect_to );
65 exit;
66 }
67
68 if ( wpas_get_option( 'gdpr_notice_short_desc_01', false ) && wpas_get_option( 'gdpr_notice_mandatory_01', true) && ! isset( $data['wpas_gdpr01'] ) ) {
69 wpas_add_error( 'accept_gdpr01_conditions', sprintf( $x_content, esc_html( wpas_get_option( 'gdpr_notice_short_desc_01', false ) ) ) );
70 wp_safe_redirect( $redirect_to );
71 exit;
72 }
73
74 if ( wpas_get_option( 'gdpr_notice_short_desc_02', false ) && wpas_get_option( 'gdpr_notice_mandatory_02', true) && ! isset( $data['wpas_gdpr02'] ) ) {
75 wpas_add_error( 'accept_gdpr02_conditions', sprintf( $x_content, esc_html( wpas_get_option( 'gdpr_notice_short_desc_02', false ) ) ) );
76 wp_safe_redirect( $redirect_to );
77 exit;
78 }
79
80 if ( wpas_get_option( 'gdpr_notice_short_desc_03', false ) && wpas_get_option( 'gdpr_notice_mandatory_03', true) && ! isset( $data['wpas_gdpr03'] ) ) {
81 wpas_add_error( 'accept_gdpr03_conditions', sprintf( $x_content, esc_html( wpas_get_option( 'gdpr_notice_short_desc_03', false ) ) ) );
82 wp_safe_redirect( $redirect_to );
83 exit;
84 }
85
86 /**
87 * wpas_register_account_before hook
88 *
89 * Fired right before the user is added to the database.
90 */
91 do_action( 'wpas_register_account_before', $user );
92
93 // Try and insert the new user in the database
94 $user_id = wpas_insert_user( $user );
95
96 if ( is_wp_error( $user_id ) ) {
97
98 /**
99 * wpas_register_account_before hook
100 *
101 * Fired right after a failed attempt to register a user.
102 *
103 * @since 3.0.1
104 */
105 do_action( 'wpas_register_account_failed', $user_id, $user );
106
107 $errors = implode( '<br>', $user_id->get_error_messages() );
108
109 wpas_add_error( 'missing_fields', $errors );
110 wp_safe_redirect( $redirect_to );
111
112 exit;
113
114 } else {
115
116 // Mark new user if registration type is moderated
117 if( 'moderated' === $registration ) {
118 update_user_option( $user_id, 'mr_user_not_activated', 'yes' );
119 }
120
121 /**
122 * Record Term and Conditions consent
123 */
124 if ( wpas_get_option( 'terms_conditions', false ) ) {
125 $status = isset( $data['wpas_terms'] ) ? isset( $data['wpas_terms'] ) : "";
126 $opt_in = ! empty ( $status ) ? strtotime( 'NOW' ) : "";
127
128 wpas_track_consent( array(
129 'item' => wpas_get_option( 'terms_conditions', false ),
130 'status' => $status,
131 'opt_in' => $opt_in,
132 'opt_out' => "",
133 'is_tor' => true
134 ), $user_id );
135 }
136
137 /**
138 * Record GDPR 1 consent
139 */
140 if ( wpas_get_option( 'gdpr_notice_short_desc_01', false ) ) {
141 $status = isset( $data['wpas_gdpr01'] ) ? isset( $data['wpas_gdpr01'] ) : "";
142 $opt_in = ! empty ( $status ) ? strtotime( 'NOW' ) : "";
143 $opt_out = empty ( $opt_in ) ? strtotime( 'NOW' ) : "";
144
145 wpas_track_consent( array(
146 'item' => wpas_get_option( 'gdpr_notice_short_desc_01', false ),
147 'status' => $status,
148 'opt_in' => $opt_in,
149 'opt_out' => '',
150 'is_tor' => false
151 ), $user_id );
152 }
153
154 /**
155 * Record GDPR 2 consent
156 */
157 if ( wpas_get_option( 'gdpr_notice_short_desc_02', false ) ) {
158 $status = isset( $data['wpas_gdpr02'] ) ? isset( $data['wpas_gdpr02'] ) : "";
159 $opt_in = ! empty ( $status ) ? strtotime( 'NOW' ) : "";
160 $opt_out = empty ( $opt_in ) ? strtotime( 'NOW' ) : "";
161
162 wpas_track_consent( array(
163 'item' => wpas_get_option( 'gdpr_notice_short_desc_02', false ),
164 'status' => $status,
165 'opt_in' => $opt_in,
166 'opt_out' => '',
167 'is_tor' => false
168 ), $user_id );
169 }
170
171 /**
172 * Record GDPR 3 consent
173 */
174 if ( wpas_get_option( 'gdpr_notice_short_desc_03', false ) ) {
175 $status = isset( $data['wpas_gdpr03'] ) ? isset( $data['wpas_gdpr03'] ) : "";
176 $opt_in = ! empty ( $status ) ? strtotime( 'NOW' ) : "";
177 $opt_out = empty ( $opt_in ) ? strtotime( 'NOW' ) : "";
178
179 wpas_track_consent( array(
180 'item' => wpas_get_option( 'gdpr_notice_short_desc_03', false ),
181 'status' => $status,
182 'opt_in' => $opt_in,
183 'opt_out' => '',
184 'is_tor' => false
185 ), $user_id );
186 }
187
188 /**
189 * wpas_register_account_before hook
190 *
191 * Fired right after the user is successfully added to the database.
192 *
193 * @since 3.0.1
194 */
195 do_action( 'wpas_register_account_after', $user_id, $user, $data );
196
197 // For moderated registration print message and redirect, so we don't auto login.
198 if( 'moderated' === $registration ) {
199 update_user_option( $user_id, 'mr_user_not_activated', 'yes' );
200
201 wpas_add_notification( 'moderated_account_created', wp_kses( wpas_get_option( 'mr_success_message' ), get_allowed_html_wp_notifications() ) );
202 wp_safe_redirect( $redirect_to );
203 exit;
204 }
205
206 if ( headers_sent() ) {
207 wpas_add_notification( 'account_created', esc_html__( 'Your account has been created. Please log-in.', 'awesome-support' ) );
208 wp_safe_redirect( $redirect_to );
209 exit;
210 }
211
212 if ( ! is_user_logged_in() ) {
213
214 /* Automatically log the user in */
215 wp_set_current_user( $user_id, get_user_by( 'ID', $user_id )->data->user_email );
216 wp_set_auth_cookie( $user_id );
217
218 wp_safe_redirect( $redirect_to );
219 exit;
220 }
221
222 }
223
224 }
225
226 /**
227 * Insert a new Awesome Support user in the WordPress users table
228 *
229 * @since 3.3.2
230 *
231 * @param array $data The user data to insert
232 * @param bool $notify Whether or not to send a notification e-mail to the newly created user
233 *
234 * @return int|WP_Error The new user ID or an error object on failure
235 */
236 function wpas_insert_user( $data = array(), $notify = true ) {
237
238 // Set the default and required user info
239 $defaults = apply_filters( 'wpas_insert_user_default_args', array(
240 'email' => '',
241 'first_name' => '',
242 'last_name' => '',
243 'pwd' => '',
244 ) );
245
246 // Set our user ID to false in the beginning
247 $user_id = false;
248
249 // Set our final user data array
250 $user = apply_filters( 'wpas_insert_user_args', array_merge( $defaults, $data ) );
251
252 // Now we need to make sure that all the required fields are filled before creating the user
253 foreach ( $defaults as $field => $value ) {
254
255 if ( empty( $user[ $field ] ) ) {
256
257 // Create the WP_Error object if it doesn't exist yet
258 if ( false === $user_id ) {
259 $user_id = new WP_Error();
260 }
261
262 // translators: %s is the name of the mandatory field.
263 $x_content = __( 'The %s field is mandatory for registering an account', 'awesome-support' );
264
265 // Add a new error to the object
266 $user_id->add( 'missing_field_' . $field, sprintf( esc_html($x_content), ucwords( str_replace( '_', ' ', $field ) ) ) );
267
268 }
269
270 }
271
272 // Only proceed with the insertion process if there is no error so far
273 if ( false === $user_id ) {
274
275 // Now that we know we have all the minimum required information, let's sanitize the user input
276 foreach ( $user as $field => $value ) {
277
278 switch ( $field ) {
279
280 case 'email':
281 $user[ $field ] = sanitize_email( $value );
282 break;
283
284 case 'pwd':
285 $user[ $field ] = $value; // No sanitization of the password
286 break;
287
288 default:
289 $user[ $field ] = sanitize_text_field( $value );
290 break;
291
292 }
293
294 }
295
296 // Let's create the user username and make sure it's unique
297 if ( isset( $data['user_login'] ) ) {
298 $username = $data['user_login'];
299 $username = wpas_check_duplicate_user_name( $username ) ;
300 } else {
301 $username = wpas_create_user_name( $user ) ; // This function will create a user name AND automatically check and fix duplicates
302 }
303
304 $registration_type = wpas_get_option( 'allow_registrations', 'allow' );
305 $new_user_role = 'moderated' === $registration_type ? wpas_get_option( 'moderated_pending_user_role' ) : wpas_get_option( 'new_user_role', 'wpas_user' );
306
307 /**
308 * wpas_insert_user_data filter
309 *
310 * @since 3.1.5
311 * @var array User account arguments
312 */
313 $args = apply_filters( 'wpas_insert_user_data', array(
314 'user_login' => $username,
315 'user_email' => $user['email'],
316 'first_name' => $user['first_name'],
317 'last_name' => $user['last_name'],
318 'display_name' => "{$user['first_name']} {$user['last_name']}",
319 'user_pass' => $user['pwd'],
320 'role' => $new_user_role,
321 ) );
322
323 /**
324 * Give a chance to third-parties to add new checks to the account registration process
325 *
326 * @since 3.2.0
327 * @var false|WP_Error
328 */
329 $user_id = apply_filters( 'wpas_register_account_errors', $user_id, $args['first_name'], $args['last_name'], $args['user_email'] );
330
331 if ( ! is_wp_error( $user_id ) ) {
332
333 /**
334 * wpas_register_account_before hook
335 *
336 * Fired right before the user is added to the database.
337 */
338 do_action( 'wpas_insert_user_before', $args );
339
340 $user_id = wp_insert_user( $args );
341
342 /**
343 * Fire up another hook after the user has been inserted
344 *
345 * @since 3.3.2
346 *
347 * @param int|WP_Error $user_id The user ID or a WP_Error object
348 * @param array $args The user data
349 */
350 do_action( 'wpas_insert_user_after', $user_id, $args );
351
352 // Notify the new user if needed
353 if ( ! is_wp_error( $user_id ) && true === apply_filters( 'wpas_new_user_notification', $notify ) ) {
354
355 $receive_alert = wpas_get_option('reg_notify_users', 'both'); // Who should receive alerts?
356
357 if ( 'none' <> $receive_alert ) {
358 wp_new_user_notification( $user_id, null, $receive_alert );
359 }
360
361 }
362
363 }
364
365 }
366
367 return $user_id;
368
369 }
370
371 /**
372 * Create the user name for a user being added
373 *
374 * @since 4.4.0
375 *
376 * @param array $user_args An array that contains the current user information
377 *
378 * @return string username
379 */
380 function wpas_create_user_name( $user_args ) {
381
382 $name_ary = explode( '@', $user_args['email'] ); // extract whatever name we can from the email address...
383
384 $user_name_construction = (int) wpas_get_option( 'reg_user_name_construction', 6 ); // get setting for how user name is to be constructed...
385
386 $user_name = '' ; // initialize the user name variable...
387
388 switch ( $user_name_construction ) {
389 case 0 :
390 // use the first part of the email address
391 $user_name = strtolower( $name_ary[0] );
392 break;
393
394 case 1:
395 // use the full email address
396 $user_name = strtolower( $user_args['email'] );
397 break;
398
399 case 2:
400 // use a random number
401 $user_name = wp_rand();
402 break;
403
404 case 3:
405 // use a guid
406 $user_name = wpas_create_pseudo_guid();
407 break;
408
409 case 4:
410 // user the first name
411 $user_name = strtolower( $user_args['first_name'] );
412 break ;
413
414 case 5:
415 // user the last name
416 $user_name = strtolower( $user_args['last_name'] );
417 break ;
418
419 case 6:
420 // user the first and last name name
421 $user_name = strtolower( $user_args['first_name'] . $user_args['last_name'] );
422 break ;
423
424 default:
425 $user_name = $user_args['first_name'] . $user_args['last_name'] ;
426 break;
427 }
428
429 // Now verify that the selected username is not already in use.
430 // If it is, append a postfix and return it.
431 return wpas_check_duplicate_user_name( $user_name );
432
433 }
434
435 /**
436 * Check to see if a username is a duplicate
437 *
438 * If the user name is a duplicate, append a postfix and return it.
439 *
440 * @since 4.4.0
441 *
442 * @param string $user_name
443 *
444 * @return string username
445 */
446 function wpas_check_duplicate_user_name( $user_name ) {
447
448 $user_check = get_user_by( 'login', $user_name );
449
450 if ( is_a( $user_check, 'WP_User' ) ) {
451 $suffix = 1;
452 do {
453 $alt_username = sanitize_user( $user_name . $suffix );
454 $user_check = get_user_by( 'login', $alt_username );
455 $suffix ++;
456 } while ( is_a( $user_check, 'WP_User' ) );
457 $user_name = $alt_username;
458 }
459
460 return $user_name ;
461
462 }
463
464 add_action( 'wpas_do_login', 'wpas_try_login' );
465 /**
466 * Try to log the user in.
467 *
468 * This function is hooked onto wpas_do_login so that the login process can be triggered
469 * when the login form is submitted.
470 *
471 * @since 2.0
472 *
473 * @param array $data Function arguments (the superglobal vars if the function is triggered by wpas_do_login)
474 *
475 * @return void
476 */
477 function wpas_try_login( $data ) {
478
479 /**
480 * Try to log the user if credentials are submitted.
481 */
482 if ( isset( $data['wpas_log'] ) ) {
483
484 // Get the redirect URL
485 $redirect_to = home_url();
486
487 if ( isset( $data['redirect_to'] ) ) {
488 $redirect_to = wp_sanitize_redirect( $data['redirect_to'] ); // If a redirect URL is specified we use it
489 } else {
490
491 global $post;
492
493 // Otherwise we try to get the URL of the originating page
494 if ( isset( $post ) && $post instanceof WP_Post ) {
495 $redirect_to = wp_sanitize_redirect( get_permalink( $post->ID ) );
496 }
497
498 }
499
500 $credentials = array(
501 'user_login' => $data['wpas_log'],
502 );
503
504 if ( isset( $data['rememberme'] ) ) {
505 $credentials['remember'] = true;
506 }
507
508 $credentials['user_password'] = isset( $data['wpas_pwd'] ) ? $data['wpas_pwd'] : '';
509
510 /**
511 * Give a chance to third-parties to add new checks to the login process
512 *
513 * @since 3.2.0
514 * @var bool|WP_Error
515 */
516 $login = apply_filters( 'wpas_try_login', false );
517
518 if ( is_wp_error( $login ) ) {
519 $error = $login->get_error_message();
520 wpas_add_error( 'login_failed', $error );
521 wp_safe_redirect( $redirect_to );
522 exit;
523 }
524
525 $login = wp_signon( $credentials );
526
527 if ( is_wp_error( $login ) ) {
528
529 $code = $login->get_error_code();
530 $error = $login->get_error_message();
531
532 // Pre-populate the user login if the problem is with the password
533 if ( 'incorrect_password' === $code ) {
534 $redirect_to = add_query_arg( 'wpas_log', $credentials['user_login'], $redirect_to );
535 }
536
537 wpas_add_error( 'login_failed', $error );
538 wp_safe_redirect( $redirect_to );
539 exit;
540
541 } elseif ( $login instanceof WP_User ) {
542
543 $user_not_activated = get_user_option( 'mr_user_not_activated', $login->ID );
544 // Logout if user is not activated and print message
545 if( 'yes' === $user_not_activated ) {
546 wp_logout();
547 wpas_add_error( 'login_not_activated', __( 'Your account is not activated yet. Try again later', 'awesome-support' ) );
548 wp_safe_redirect( $redirect_to );
549 exit;
550 }
551
552 // Filter to allow redirection of successful login
553 $redirect_to = apply_filters( 'wpas_try_login_redirect', $redirect_to, $redirect_to, $login );
554
555 wp_safe_redirect( $redirect_to );
556 exit;
557
558 } else {
559 wpas_add_error( 'login_failed', __( 'We were unable to log you in for an unknown reason.', 'awesome-support' ) );
560 wp_safe_redirect( $redirect_to );
561 exit;
562 }
563
564 }
565
566 }
567
568 /**
569 * Block login for moderated (not yet activated) users.
570 *
571 * The existing check in wpas_try_login() only blocks login via the AS frontend
572 * form. This filter blocks login via ALL flows including /wp-login.php.
573 *
574 * @since 6.4.0
575 *
576 * @param WP_User|WP_Error $user
577 * @param string $username
578 * @param string $password
579 *
580 * @return WP_User|WP_Error
581 */
582 add_filter( 'authenticate', 'wpas_block_moderated_user_login', 99, 3 );
583 function wpas_block_moderated_user_login( $user, $username, $password ) {
584 if ( $user instanceof WP_User ) {
585 if ( 'yes' === get_user_option( 'mr_user_not_activated', $user->ID ) ) {
586 return new WP_Error(
587 'mr_not_activated',
588 __( 'Your account is not activated yet. Try again later', 'awesome-support' )
589 );
590 }
591 }
592 return $user;
593 }
594
595 /**
596 * Checks if a user can view a ticket.
597 *
598 * @since 2.0.0
599 *
600 * @param integer $post_id ID of the post to display
601 *
602 * @return boolean
603 */
604 function wpas_can_view_ticket( $post_id ) {
605
606 /**
607 * Set the return value to false by default to avoid giving unwanted access.
608 */
609 $can = false;
610
611 /**
612 * Get the post data.
613 */
614 $post = get_post( $post_id );
615 $author_id = null;
616
617 if (!empty($post)) {
618
619 /**
620 * Get author and agent ids on the ticket
621 */
622 $author_id = intval( $post->post_author );
623
624 if ( is_user_logged_in() ) {
625 if ( ( get_current_user_id() === $author_id && current_user_can( 'view_ticket' ) )
626 || ( wpas_is_user_agent_on_ticket( $post_id ) && current_user_can( 'view_ticket' ) )
627 || wpas_can_user_see_all_tickets() ) {
628 $can = true;
629 }
630 }
631
632 }
633
634 return apply_filters( 'wpas_can_view_ticket', $can, $post_id, $author_id );
635
636 }
637
638 /**
639 * Check if user can see all tickets
640 *
641 * @global object $current_user
642 * @return boolean
643 */
644 function wpas_can_user_see_all_tickets() {
645
646 $user_can_see_all = false;
647
648 /* Check if admins can see all tickets */
649 if ( wpas_is_asadmin() && true === (bool) wpas_get_option( 'admin_see_all' ) ) {
650 $user_can_see_all = true;
651 }
652
653 /* Check if agents can see all tickets */
654 if ( wpas_is_agent() && ! wpas_is_asadmin() && true === (bool) wpas_get_option( 'agent_see_all' ) ) {
655 $user_can_see_all = true;
656 }
657
658 global $current_user;
659
660 /* If current user can see all tickets */
661 if ( current_user_can( 'view_all_tickets' ) || true === (bool) get_user_option( 'wpas_view_all_tickets', (int) $current_user->ID ) ) {
662 $user_can_see_all = true;
663 }
664
665 return $user_can_see_all;
666 }
667
668 /**
669 * Check if the current user can reply from the frontend.
670 *
671 * @since 2.0.0
672 *
673 * @param boolean $admins_allowed Shall admins/agents be allowed to reply from the frontend
674 * @param integer $post_id ID of the ticket to check
675 *
676 * @return boolean True if the user can reply
677 */
678 function wpas_can_reply_ticket( $admins_allowed = false, $post_id = null ) {
679
680 if ( is_null( $post_id ) ) {
681 global $post;
682 $post_id = $post->ID;
683 }
684
685 $admins_allowed = apply_filters( 'wpas_can_agent_reply_frontend', $admins_allowed ); /* Allow admins to post through front-end. The filter overwrites the function parameter. */
686 $post = get_post( $post_id );
687 $author_id = $post->post_author;
688
689 if ( is_user_logged_in() ) {
690
691 global $current_user;
692
693 if ( ! current_user_can( 'reply_ticket' ) ) {
694 // return false;
695 return apply_filters( 'wpas_can_also_reply_ticket', false, $post_id, $author_id, 1 );
696 }
697
698 $user_id = $current_user->data->ID;
699
700 /* If the current user is the author then yes */
701 if ( $user_id == $author_id ) {
702 // return true;
703 return apply_filters( 'wpas_can_also_reply_ticket', true, $post_id, $author_id, 2 );
704 } else {
705
706 if ( current_user_can( 'edit_ticket' ) && true === $admins_allowed ) {
707 // return true;
708 return apply_filters( 'wpas_can_also_reply_ticket', true, $post_id, $author_id, 3 );
709 } else {
710 // return false;
711 return apply_filters( 'wpas_can_also_reply_ticket', false, $post_id, $author_id, 4 );
712 }
713
714 }
715
716 } else {
717 // return false;
718 return apply_filters( 'wpas_can_also_reply_ticket', false, $post_id, $author_id, 5 );
719 }
720
721 }
722
723 /**
724 * Get user role nicely formatted.
725 *
726 * @since 3.0.0
727 *
728 * @param string $role User role
729 *
730 * @return string Nicely formatted user role
731 */
732 function wpas_get_user_nice_role( $role ) {
733
734 /* Get first role if role is an array */
735 if ( is_array($role) ) {
736 // The two lines below have to be separate instead of embedded inside each other in order to avoid an "Only variables should be passed by reference" error
737 $role = array_values( $role );
738 $role = array_shift( $role ) ;
739 }
740
741 /* Remove the prefix on WPAS roles */
742 if ( 'wpas_' === substr( $role, 0, 5 ) ) {
743 $role = substr( $role, 5 );
744 }
745
746 /* Remove separators */
747 $role = str_replace( array( '-', '_' ), ' ', $role );
748
749 return ucwords( $role );
750
751 }
752
753 /**
754 * Check if the current user has the permission to open a ticket
755 *
756 * If a ticket ID is given we make sure the ticket author is the current user.
757 * This is used for checking if a user can re-open a ticket.
758 *
759 * @param int $ticket_id
760 *
761 * @return bool
762 */
763 function wpas_can_submit_ticket( $ticket_id = 0 ) {
764
765 $can = false;
766
767 if ( is_user_logged_in() ) {
768
769 if ( current_user_can( 'create_ticket' ) ) {
770 $can = true;
771 }
772
773 if ( 0 !== $ticket_id ) {
774
775 $ticket = get_post( $ticket_id );
776
777 if ( is_object( $ticket ) && is_a( $ticket, 'WP_Post' ) && get_current_user_id() !== (int) $ticket->post_author ) {
778 $can = false;
779 }
780
781 }
782
783 }
784
785 return apply_filters( 'wpas_can_submit_ticket', $can );
786
787 }
788
789 /**
790 * Get a list of users that belong to the plugin.
791 *
792 * @since 3.1.8
793 *
794 * @param array $args Arguments used to filter the users
795 *
796 * @return array An array of users objects
797 */
798 function wpas_get_users( $args = array() ) {
799
800 $defaults = array(
801 'exclude' => array(),
802 'cap' => '',
803 'cap_exclude' => '',
804 'orderby' => 'ID',
805 'order' => 'ASC',
806 'search' => array(),
807 'ids' => array()
808 );
809
810 /* The array where we save all users we want to keep. */
811 $list = array();
812
813 /* Merge arguments. */
814 $args = wp_parse_args( $args, $defaults );
815 $users = new WPAS_Member_Query( $args );
816
817 return apply_filters( 'wpas_get_users', $users );
818
819 }
820
821 /**
822 * Get all Awesome Support members
823 *
824 * @since 3.3
825 * @return array
826 */
827 function wpas_get_members() {
828
829 global $wpdb;
830
831 $query = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE 1 LIMIT 0, 2000" );
832
833 if ( empty( $query ) ) {
834 return $query;
835 }
836
837 return wpas_users_sql_result_to_wpas_member( $query );
838
839 }
840
841 /**
842 * Get all Awesome Support members by their user ID
843 *
844 * @since 3.3
845 *
846 * @param $ids
847 *
848 * @return array
849 */
850 function wpas_get_members_by_id( $ids ) {
851
852 if ( ! is_array( $ids ) ) {
853 $ids = (array) $ids;
854 }
855
856 // Prepare the IDs query var
857 $ids = implode( ',', $ids );
858
859 global $wpdb;
860
861 $query = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ('$ids')" );
862
863 if ( empty( $query ) ) {
864 return $query;
865 }
866
867 return wpas_users_sql_result_to_wpas_member( $query );
868
869 }
870
871 /**
872 * Transform a users SQL query into WPAS_Member_User objects
873 *
874 * @param array $results SQL results
875 * @param string $class The WPAS_Member subclass to use. Possible values are user and agent
876 *
877 * @return array
878 */
879 function wpas_users_sql_result_to_wpas_member( $results, $class = 'user' ) {
880
881 $users = array();
882 $class_name = '';
883
884 switch ( $class ) {
885
886 case 'user':
887 $class_name = 'WPAS_Member_User';
888 break;
889
890 case 'agent':
891 $class_name = 'WPAS_member_Agent';
892 break;
893
894 }
895
896 if ( empty( $class_name ) ) {
897 return array();
898 }
899
900 foreach ( $results as $user ) {
901
902 $usr = new $class_name( $user );
903
904 if ( true === $usr->is_member() ) {
905 $users[] = $usr;
906 }
907
908 }
909
910 return $users;
911
912 }
913
914 /**
915 * Count the total number of users in the database
916 *
917 * @since 3.3
918 * @return int
919 */
920 function wpas_count_wp_users() {
921
922 $count = get_transient( 'wpas_wp_users_count' );
923
924 if ( false === $count ) {
925
926 global $wpdb;
927
928 $query = $wpdb->get_results( "SELECT ID FROM $wpdb->users WHERE 1" );
929 $count = count( $query );
930
931 set_transient( 'wpas_wp_users_count', $count, apply_filters( 'wpas_wp_users_count_transient_lifetime', 604800 ) ); // Default to 1 week
932
933 }
934
935 return $count;
936
937 }
938
939 /**
940 * Check if the WP database has too many users or not
941 *
942 * @since 3.3
943 * @return bool
944 */
945 function wpas_has_too_many_users() {
946
947 // We consider 3000 users to be too many to query at once
948 $limit = apply_filters( 'wpas_has_too_many_users_limit', 3000 );
949
950 if ( wpas_count_wp_users() > $limit ) {
951 return true;
952 }
953
954 return false;
955
956 }
957
958 add_action( 'user_register', 'wpas_clear_get_users_cache' );
959 add_action( 'delete_user', 'wpas_clear_get_users_cache' );
960 add_action( 'profile_update', 'wpas_clear_get_users_cache' );
961 /**
962 * Clear all the users lists transients
963 *
964 * If a new admin / agent is added, deleted or edited while the users list transient
965 * is still valid then the user won't appear / disappear from the users lists
966 * until the transient expires. In order to avoid this issue we clear the transients
967 * when one of the above actions is executed.
968 *
969 * @since 3.2.0
970 * @return void
971 */
972 function wpas_clear_get_users_cache() {
973
974 global $wpdb;
975 $sql = "DELETE FROM $wpdb->options WHERE option_name LIKE '%s'";
976 $wpdb->get_results( $wpdb->prepare( "$sql", '_transient_wpas_list_users_%' ) );
977
978 }
979
980 /**
981 * List users.
982 *
983 * Returns a list of users based on the required
984 * capability. If the capability is "all", all site
985 * users are returned.
986 *
987 * @param string $cap Minimum capability the user must have to be added to the list
988 *
989 * @return array A list of users
990 * @since 3.0.0
991 */
992 function wpas_list_users( $cap = 'all' ) {
993
994 $list = array();
995
996 /* List all users */
997 $all_users = wpas_get_users( array( 'cap' => $cap ) );
998
999 foreach ( $all_users->members as $user ) {
1000 $user_id = $user->ID;
1001 $user_name = $user->display_name;
1002 $list[ $user_id ] = $user_name;
1003 }
1004
1005 return apply_filters( 'wpas_users_list', $list );
1006
1007 }
1008
1009 /**
1010 * Creates a dropdown list of users.
1011 *
1012 * @since 3.1.2
1013 * @param array $args Arguments
1014 * @return string Users dropdown
1015 */
1016 function wpas_users_dropdown( $args = array() ) {
1017
1018 global $current_user, $post;
1019
1020 $defaults = array(
1021 'name' => 'wpas_user',
1022 'id' => '',
1023 'class' => '',
1024 'exclude' => array(),
1025 'selected' => '',
1026 'cap' => '',
1027 'cap_exclude' => '',
1028 'orderby' => 'ID',
1029 'order' => 'ASC',
1030 'agent_fallback' => false,
1031 'please_select' => false,
1032 'select2' => false,
1033 'disabled' => false,
1034 'data_attr' => array(),
1035 'ids' => array()
1036 );
1037
1038 $args = wp_parse_args( $args, $defaults );
1039
1040 /* List all users */
1041 $all_users = wpas_get_users( array( 'cap' => $args['cap'], 'cap_exclude' => $args['cap_exclude'], 'exclude' => $args['exclude'], 'ids' => $args['ids'], 'orderby' => $args['orderby'], 'order' => $args['order'] ) );
1042
1043 /**
1044 * We use a marker to keep track of when a user was selected.
1045 * This allows for adding a fallback if nobody was selected.
1046 *
1047 * @var boolean
1048 */
1049 $marker = false;
1050
1051 $options = '';
1052
1053 /* The ticket is being created, use the current user by default */
1054 if ( ! empty( $args['selected'] ) ) {
1055 $user = get_user_by( 'id', intval( $args['selected'] ) );
1056 if ( false !== $user && ! is_wp_error( $user ) ) {
1057 $marker = true;
1058 $options .= "<option value='{$user->ID}' selected='selected'>{$user->data->display_name}</option>";
1059 }
1060 }
1061
1062 if( $all_users && !is_null( $all_users->members ) && !empty( $all_users->members ) )
1063 {
1064 foreach ( $all_users->members as $user ) {
1065
1066 /* This user was already added, skip it */
1067 if ( ! empty( $args['selected'] ) && intval( $user->user_id ) === intval( $args['selected'] ) ) {
1068 continue;
1069 }
1070
1071 $user_id = $user->ID;
1072 $user_name = $user->display_name;
1073 $selected_attr = '';
1074
1075 if ( false === $marker ) {
1076 if ( false !== $args['selected'] ) {
1077 if ( ! empty( $args['selected'] ) ) {
1078 if ( $args['selected'] === $user_id ) {
1079 $selected_attr = 'selected="selected"';
1080 }
1081 } else {
1082 if ( isset( $post ) && $user_id == $post->post_author ) {
1083 $selected_attr = 'selected="selected"';
1084 }
1085 }
1086 }
1087 }
1088
1089 /* Set the marker as true to avoid selecting more than one user */
1090 if ( ! empty( $selected_attr ) ) {
1091 $marker = true;
1092 }
1093
1094 /* Output the option */
1095 $options .= "<option value='$user_id' $selected_attr>$user_name</option>";
1096
1097 }
1098 }
1099
1100 /* In case there is no selected user yet we add the post author, or the currently logged user (most likely an admin) */
1101 if ( true === $args['agent_fallback'] && false === $marker ) {
1102 $fallback = $current_user;
1103 $fb_selected = false === $marker ? 'selected="selected"' : '';
1104 $options .= "<option value='{$fallback->ID}' $fb_selected>{$fallback->data->display_name}</option>";
1105 }
1106
1107 $contents = wpas_dropdown( wp_parse_args( $args, $defaults ), $options );
1108
1109 return $contents;
1110
1111 }
1112
1113 /**
1114 * Display a dropdown of the support users.
1115 *
1116 * Wrapper function for wpas_users_dropdown where
1117 * the cap_exclude is set to exclude all users with
1118 * the capability to edit a ticket.
1119 *
1120 * @since 3.1.3
1121 * @param array $args Arguments
1122 * @return string HTML dropdown
1123 */
1124 function wpas_support_users_dropdown( $args = array() ) {
1125 $args['cap_exclude'] = 'edit_ticket';
1126 $args['cap'] = 'create_ticket';
1127 //This has been verify by html tags ted.
1128 echo wp_kses(wpas_users_dropdown( $args ), wpas_dropdown_allowed_html_tags());
1129 }
1130
1131 /**
1132 * Wrapper function to easily get a user tickets
1133 *
1134 * This function is a wrapper for wpas_get_user_tickets() with the user ID preset
1135 *
1136 * @since 3.2.2
1137 *
1138 * @param int $user_id
1139 * @param string $ticket_status
1140 * @param string $post_status
1141 *
1142 * @return array
1143 */
1144 function wpas_get_user_tickets( $user_id = 0, $ticket_status = 'open', $post_status = 'any' ) {
1145
1146 if ( 0 === $user_id ) {
1147 $user_id = get_current_user_id();
1148 }
1149
1150 $args = array(
1151 'author' => $user_id,
1152 );
1153
1154 $tickets = wpas_get_tickets( $ticket_status, $args, $post_status );
1155
1156 return $tickets;
1157
1158 }
1159
1160 add_filter( 'authenticate', 'wpas_email_signon', 20, 3 );
1161 /**
1162 * Allow e-mail to be used as the login.
1163 *
1164 * @since 3.0.2
1165 *
1166 * @param WP_User|WP_Error|null $user User to authenticate.
1167 * @param string $username User login
1168 * @param string $password User password
1169 *
1170 * @return object WP_User if authentication succeed, WP_Error on failure
1171 */
1172 function wpas_email_signon( $user, $username, $password ) {
1173
1174 /* Authentication was successful, we don't touch it */
1175 if ( is_object( $user ) && is_a( $user, 'WP_User' ) ) {
1176 return $user;
1177 }
1178
1179 /**
1180 * If the $user isn't a WP_User object nor a WP_Error
1181 * we don' touch it and let WordPress handle it.
1182 */
1183 if ( ! is_wp_error( $user ) ) {
1184 return $user;
1185 }
1186
1187 /**
1188 * We only wanna alter the authentication process if the username was rejected.
1189 * If the error is different, we let WordPress handle it.
1190 */
1191 if ( 'invalid_username' !== $user->get_error_code() ) {
1192 return $user;
1193 }
1194
1195 /**
1196 * If the username is not an e-mail there is nothing else we can do,
1197 * the error is probably legitimate.
1198 */
1199 if ( ! is_email( $username ) ) {
1200 return $user;
1201 }
1202
1203 /* Try to get the user with this e-mail address */
1204 $user_data = get_user_by( 'email', $username );
1205
1206 /**
1207 * If there is no user with this e-mail the error is legitimate
1208 * so let's just return it.
1209 */
1210 if ( false === $user_data || ! is_a( $user_data, 'WP_User' ) ) {
1211 return $user;
1212 }
1213
1214 return wp_authenticate_username_password( null, $user_data->data->user_login, $password );
1215
1216 }
1217
1218 add_action( 'wp_ajax_nopriv_email_validation', 'wpas_mailgun_check' );
1219 /**
1220 * Check if an e-mail is valid during registration using the MailGun API
1221 *
1222 * @param string $data
1223 */
1224 function wpas_mailgun_check( $data = '' ) {
1225
1226 if ( empty( $data ) ) {
1227 if ( isset( $_POST ) ) {
1228 $data = $_POST;
1229 } else {
1230 echo '';
1231 die();
1232 }
1233 }
1234
1235 if ( ! isset( $data['email'] ) ) {
1236 echo '';
1237 die();
1238 }
1239
1240 if ( ! current_user_can( 'read' ) ) {
1241 wp_send_json_error( array('message' => __('Unauthorized action. You do not have permission to check if an e-mail is valid during registration using the MailGun API.', 'awesome-support') ), 403);
1242 }
1243
1244 $mailgun = new WPAS_MailGun_EMail_Check();
1245 $check = $mailgun->check_email( $data );
1246
1247 if ( ! is_wp_error( $check ) ) {
1248
1249 $check = json_decode( $check );
1250
1251 if ( is_object( $check ) && isset( $check->did_you_mean ) && ! is_null( $check->did_you_mean ) ) {
1252 // translators: %s is the supposed value.
1253 $x_content = __( 'Did you mean %s', 'awesome-support' );
1254 printf( wp_kses_post( $x_content, "<strong>{$check->did_you_mean}</strong>?" ) );
1255 die();
1256 }
1257
1258 }
1259
1260 die();
1261
1262 }
1263
1264 add_action( 'wp_ajax_wpas_get_users', 'wpas_get_users_ajax',11,0 );
1265 /**
1266 * Get AS users using Ajax
1267 *
1268 * @since 3.3
1269 *
1270 * @param array $args Query parameters
1271 *
1272 * @return void
1273 */
1274 function wpas_get_users_ajax( $args = array() ) {
1275
1276 global $wpdb;
1277
1278 /**
1279 * Security checking. Verify ajax via nonce.
1280 */
1281 if( !check_ajax_referer( 'wpas-get-users', 'get_users_nonce', false ) ) {
1282
1283 wp_send_json_error( array( 'message' => "You don't have access to perform this action." ) );
1284 die();
1285 }
1286
1287 //Check permission for capability of current user
1288 if ( ! current_user_can( 'edit_ticket' ) ) {
1289 wp_send_json_error( array( 'message' => "You don't have access to perform this action." ) );
1290 die();
1291 }
1292
1293 $defaults = array(
1294 'cap' => 'edit_ticket',
1295 'cap_exclude' => '',
1296 'exclude' => '',
1297 'q' => '', // The search query
1298 );
1299
1300 if ( empty( $args ) ) {
1301 $args = array();
1302 foreach ( $defaults as $key => $value ) {
1303 if ( isset( $_POST[ $key ] ) ) {
1304 $args[ $key ] = sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
1305 }
1306 }
1307 }
1308
1309 $args = wp_parse_args( $args, $defaults );
1310
1311 $department_assignment = get_user_option( 'wpas_department_assignment', get_current_user_id() );
1312 $ids = [];
1313 if (!empty($department_assignment)) {
1314 $args_user = array(
1315 'meta_key' => $wpdb->get_blog_prefix() . 'wpas_department',
1316 'meta_compare' => 'EXISTS'
1317 );
1318
1319 $user_query = new WP_User_Query( $args_user );
1320
1321 if (! empty( $user_query->get_results() )) {
1322 foreach ( $user_query->get_results() as $user ) {
1323 $departments = get_user_option( 'wpas_department', $user->ID );
1324 if (!empty($departments)) {
1325 foreach ($departments as $department) {
1326 if (in_array($department, $department_assignment)) {
1327 $ids[] = $user->ID;
1328 break;
1329 }
1330 }
1331 }
1332 }
1333 }
1334 }
1335
1336 /**
1337 * @var WPAS_Member_Query $users
1338 */
1339 $users = wpas_get_users(
1340 array(
1341 'cap' => array_map( 'sanitize_text_field', array_filter( (array) $args['cap'] ) ),
1342 'cap_exclude' => array_map( 'sanitize_text_field', array_filter( (array) $args['cap_exclude'] ) ),
1343 'exclude' => array_map( 'intval', array_filter( (array) $args['exclude'] ) ),
1344 'ids' => array_map( 'intval', array_filter( (array) $ids ) ),
1345 'search' => array(
1346 'query' => sanitize_text_field( esc_sql( $args['q'] )),
1347 'fields' => array( 'user_nicename', 'display_name', 'id', 'user_email' ),
1348 'relation' => 'OR'
1349 )
1350 )
1351 );
1352
1353 $result = array();
1354 if( $users && !is_null( $users->members ) && !empty( $users->members ) )
1355 {
1356 foreach ( $users->members as $user ) {
1357
1358 $result[] = array(
1359 'user_id' => $user->ID,
1360 'user_name' => $user->display_name,
1361 'user_email' => $user->user_email,
1362 'user_avatar' => get_avatar_url( $user->ID, array( 'size' => 32, 'default' => 'mm' ) ),
1363 );
1364
1365 }
1366 }
1367 echo json_encode( $result );
1368 die();
1369
1370 }
1371
1372 /**
1373 * Check if a user has Smart Tickets Order
1374 *
1375 * Smart Tickets Order is a custom way to order tickets in the tickets list screen. This function checks if the current
1376 * agent has enabled this option. If not, tickets will be ordered the "WordPress way".
1377 *
1378 * @param int $user_id The user ID
1379 *
1380 * @return bool
1381 */
1382 function wpas_has_smart_tickets_order( $user_id = 0 ) {
1383
1384 // Set the value to false by default
1385 $value = false;
1386
1387 if ( 0 === $user_id ) {
1388 $user_id = get_current_user_id();
1389 }
1390
1391 // If the user is not an agent this is irrelevant. Just return false.
1392 if ( user_can( $user_id, 'edit_ticket' ) ) {
1393
1394 $smart = esc_attr( get_user_option( 'wpas_smart_tickets_order', $user_id ) );
1395
1396 if ( 'yes' === $smart ) {
1397 $value = true;
1398 }
1399
1400 }
1401
1402 return apply_filters( 'wpas_has_smart_tickets_order', $value, $user_id );
1403
1404 }
1405
1406 /**
1407 * return list of agents in a ticket
1408 * @param int $ticket_id
1409 * @param array $exclude
1410 * @return array
1411 */
1412 function wpas_get_ticket_agents( $ticket_id = '' , $exclude = array() ) {
1413
1414 $agent_ids = $agents = array();
1415
1416 $primary_agent_id = intval( get_post_meta( $ticket_id, '_wpas_assignee', true ) );
1417 if( $primary_agent_id && !in_array( $primary_agent_id, $exclude ) ) {
1418 $agent_ids[] = $primary_agent_id;
1419 }
1420
1421 if( wpas_is_multi_agent_active() ) {
1422 $secondary_agent_id = intval( get_post_meta( $ticket_id, '_wpas_secondary_assignee', true ) );
1423 $tertiary_agent_id = intval( get_post_meta( $ticket_id, '_wpas_tertiary_assignee', true ) );
1424 if( $secondary_agent_id && !in_array( $secondary_agent_id, $exclude ) && !in_array( $secondary_agent_id, $agent_ids ) ) {
1425 $agent_ids[] = $secondary_agent_id;
1426 }
1427
1428 if( $tertiary_agent_id && !in_array( $tertiary_agent_id, $exclude ) && !in_array( $tertiary_agent_id, $agent_ids ) ) {
1429 $agent_ids[] = $tertiary_agent_id;
1430 }
1431 }
1432
1433 foreach ($agent_ids as $id) {
1434 $agents[] = get_user_by('id', $id);
1435 }
1436
1437 return $agents;
1438 }
1439
1440 /**
1441 * Log the user consent. Data saved in WP Option
1442 * We're not sure yet if custom table is needed but we can
1443 * extend in the future version when we see fit
1444 *
1445 * @param {*} label
1446 * @param {*} action
1447 * @param {*} date
1448 */
1449 function wpas_log_consent( $user_id, $label, $action, $date = "", $user = "" ) {
1450 /**
1451 * Label parameter is required, WP_Error if none given
1452 */
1453 if( ! $label ) {
1454 return new WP_Error( 'consent_label_missing', __( 'Consent label is required!', 'awesome-support' ) );
1455 }
1456 if( ! $action ) {
1457 return new WP_Error( 'consent_action_missing', __( 'Consent action is required! Options are - "opted-in" or "opted-out"', 'awesome-support' ) );
1458 }
1459
1460 /**
1461 * If date is not given, set it today
1462 */
1463 if( empty ( $date ) ) {
1464 $date = gmdate( 'm/d/Y', strtotime( 'NOW' ) );
1465 }
1466
1467 /**
1468 * Determine user, we need to log when admin opt out as well
1469 */
1470 if( empty ( $user ) ) {
1471 $user = __( 'user', 'awesome-support' );
1472 }
1473
1474 /**
1475 * Consent logs are stored in wpas_consent_log option
1476 */
1477 $logged_consent = get_user_option( 'wpas_consent_log', $user_id );
1478 $consent = apply_filters( 'wpas_logged_consent_new', sprintf(
1479 '%s - %s %s %s %s',
1480 $label,
1481 $user,
1482 $action,
1483 __( 'on', 'awesome-support' ),
1484 $date
1485 ) );
1486
1487 if( ! empty ( $logged_consent ) && is_array( $logged_consent ) ) {
1488 update_user_option( $user_id, 'wpas_consent_log', array_merge( $logged_consent, array( $consent ) ) );
1489 }else{
1490 update_user_option( $user_id, 'wpas_consent_log', array( $consent ) );
1491 }
1492
1493 /**
1494 * After logging consent action hook
1495 */
1496 do_action( 'wpas_log_consent_after', $user_id, $label, $action, $date , $user, $consent );
1497
1498 }
1499
1500 /**
1501 * Similar to wpas_log_consent()
1502 * This function tracks the consent instead of just
1503 * logging them. This is the primary function in consent
1504 * table information in both on user profile and on the
1505 * GDPR table in the front-end
1506 *
1507 * @param {*} data
1508 */
1509 function wpas_track_consent( $data, $user_id, $opt_type = "" ){
1510 /**
1511 * Consent logs are stored in wpas_consent_tracking option
1512 */
1513 $tracked_consent = get_user_option( 'wpas_consent_tracking', $user_id );
1514
1515 if( ! empty ( $tracked_consent ) && is_array( $tracked_consent ) ) {
1516 /**
1517 * If same item exists, simply update the same row
1518 * instead of merging them on new row
1519 */
1520 $found_key = array_search( $data['item'], array_column( $tracked_consent, 'item' ) );
1521 if( $found_key !== false && ! empty ( $opt_type ) ) {
1522 /**
1523 * We found something, update the row
1524 */
1525 foreach( $tracked_consent as $key => $value ) {
1526 if( $found_key === $key ) {
1527 if( ! empty ( $data['opt_out'] ) ) {
1528 $tracked_consent[$found_key]['opt_out']= $data['opt_out'];
1529 $tracked_consent[$found_key]['opt_in'] = $data['opt_in'];
1530 }
1531 if( ! empty ( $data['opt_in'] ) ) {
1532 $tracked_consent[$found_key]['opt_in'] = $data['opt_in'];
1533 $tracked_consent[$found_key]['opt_out'] = $data['opt_out'];
1534 }
1535 $tracked_consent[$found_key]['status'] = $data['status'];
1536 }
1537 }
1538 update_user_option( $user_id, 'wpas_consent_tracking', $tracked_consent );
1539
1540 /**
1541 * After consent tracking update existing meta action hook
1542 */
1543 do_action( 'wpas_track_consent_update_existing_after', $data, $user_id, $opt_type, $tracked_consent ) ;
1544
1545 }else{
1546 update_user_option( $user_id, 'wpas_consent_tracking', array_merge( $tracked_consent, array( $data ) ) );
1547 /**
1548 * After new consent tracking action hook
1549 */
1550 do_action( 'wpas_track_consent_update_new_too', $data, $user_id, $opt_type, $tracked_consent ) ;
1551 }
1552 }else{
1553 update_user_option( $user_id, 'wpas_consent_tracking', array( $data ) );
1554
1555 /**
1556 * After new consent tracking action hook
1557 */
1558 do_action( 'wpas_track_consent_update_new', $data, $user_id, $opt_type, $tracked_consent ) ;
1559 }
1560 /**
1561 * After consent tracking action hook
1562 */
1563 do_action( 'wpas_track_consent_after', $data, $user_id, $opt_type ) ;
1564
1565 }
1566
1567 add_action( 'wpas_register_account_after', 'wpas_moderated_registeration_notify', 11, 2 );
1568
1569 /**
1570 * Notify user and admin about moderated registration
1571 *
1572 * @param int $user_id
1573 * @param array $user
1574 */
1575 function wpas_moderated_registeration_notify( $user_id, $user ) {
1576
1577
1578 $registration_type = wpas_get_option( 'allow_registrations', 'allow' );
1579
1580 if( 'moderated' === $registration_type ) {
1581
1582 $admin_email = get_bloginfo( 'admin_email' );
1583
1584 $admin_notify = new WPAS_User_Email_Notification( $user_id, $admin_email );
1585 $admin_notify->notify( 'moderated_registration_admin' );
1586
1587
1588 $user_notify = new WPAS_User_Email_Notification( $user_id, $user['email'] );
1589 $user_notify->notify( 'moderated_registration_user' );
1590 }
1591 }
1592
1593 /**
1594 * Return moderated registration notification cases
1595 *
1596 * @return array
1597 */
1598 function wpas_mr_notification_cases() {
1599
1600 return array(
1601 'moderated_registration_admin',
1602 'moderated_registration_user',
1603 'moderated_registration_approved_user',
1604 'moderated_registration_denied_user'
1605 );
1606 }
1607
1608 add_filter( 'wpas__user_email_notifications_case_is_active', 'wpas_mr_enabled_email_notification_case', 11, 2 );
1609
1610 /**
1611 * Check if moderated registration notification is enabled
1612 *
1613 * @param boolean $enabled
1614 * @param string $case
1615 *
1616 * @return boolean
1617 */
1618 function wpas_mr_enabled_email_notification_case( $enabled, $case ) {
1619
1620
1621 $cases = wpas_mr_notification_cases();
1622
1623 if( in_array( $case, $cases ) ) {
1624 $enabled = wpas_get_option( "enable_{$case}_email", true );
1625 }
1626
1627 return $enabled;
1628 }
1629
1630
1631
1632 add_filter( 'wpas__user_email_notifications_pre_fetch_subject' , 'wpas_registration_user_email_notifications_pre_fetch_subject' ,11, 3 );
1633
1634 /**
1635 * Set email subject for moderated registration notification
1636 *
1637 * @param string $subject
1638 * @param int $user_id
1639 * @param string $case
1640 *
1641 * @return string
1642 */
1643 function wpas_registration_user_email_notifications_pre_fetch_subject( $subject, $user_id, $case ) {
1644
1645 $subject = wpas_get_option( "{$case}_email__subject" );
1646
1647 return $subject;
1648 }
1649
1650 add_filter( 'wpas__user_email_notifications_pre_fetch_content' , 'wpas_registration_user_email_notifications_pre_fetch_content' , 11, 3 );
1651
1652 /**
1653 * Set email content for moderated registration notification
1654 *
1655 * @param string $body
1656 * @param int $user_id
1657 * @param string $case
1658 *
1659 * @return string
1660 */
1661 function wpas_registration_user_email_notifications_pre_fetch_content( $body, $user_id, $case ) {
1662
1663 $body = wpas_get_option( "{$case}_email__content" );
1664
1665 return $body;
1666
1667 }
1668
1669 add_action( 'edit_user_profile', 'wpas_add_activate_user_button' , 10, 1 ); // Display tickets on user profile page
1670 add_action( 'show_user_profile', 'wpas_add_activate_user_button' , 9, 1 ); // Display tickets on user profile page
1671
1672 /**
1673 * Add activate user button on back-end edit user page
1674 *
1675 * @param object $user
1676 */
1677 function wpas_add_activate_user_button( $user ) {
1678
1679 // Only admins with edit_users capability should see these buttons
1680 if ( ! current_user_can( 'edit_users' ) ) {
1681 return;
1682 }
1683
1684 $not_activated = get_user_option( 'mr_user_not_activated', $user->ID );
1685 $user_denied = get_user_option( 'mr_user_denied', $user->ID );
1686
1687
1688 if( 'yes' === $not_activated && 'yes' !== $user_denied ) {
1689
1690 $edit_user_link = add_query_arg( 'user_id', $user->ID, self_admin_url( 'user-edit.php' ) );
1691 $activate_url = wpas_do_url( $edit_user_link, 'mr_activate_user' );
1692 $deny_url = wpas_do_url( $edit_user_link, 'mr_deny_user' );
1693
1694 printf( '<a href="%s" class="button button-primary">%s</a>', esc_url( $activate_url ), esc_html__( 'Activate User', 'awesome-support' ) );
1695
1696 printf( '<a href="%s" class="button button-primary mr-deny-user-btn">%s</a>', esc_url( $deny_url ), esc_html__( 'Deny User', 'awesome-support' ) );
1697
1698 } elseif( 'yes' === $user_denied ) {
1699 printf( '<div><p>%s</p></div>', esc_html__( 'User has been denied.', 'awesome-support' ) );
1700 }
1701
1702 }
1703
1704
1705 add_action( 'wpas_do_mr_activate_user', 'wpas_do_mr_activate_user' );
1706
1707 /**
1708 * Activate moderated user
1709 *
1710 * @param array $data
1711 */
1712 function wpas_do_mr_activate_user( $data ) {
1713
1714 $user_id = $data['user_id'];
1715
1716 if( $user_id ) {
1717
1718 // FIX: Add capability check
1719 if ( ! current_user_can( 'edit_users' ) ) {
1720 wp_die( __( 'You do not have permission to activate users.', 'awesome-support' ), 403 );
1721 }
1722
1723 // FIX: Verify current user can edit the target user
1724 if ( ! current_user_can( 'edit_user', $user_id ) ) {
1725 wp_die( __( 'You do not have permission to edit this user.', 'awesome-support' ), 403 );
1726 }
1727
1728 $role = wpas_get_option( 'moderated_activated_user_role' );
1729
1730 $updated = wp_update_user( array( 'ID' => $user_id, 'role' => $role ) );
1731
1732 if ( is_wp_error( $updated ) ) {
1733 $redirect_to = add_query_arg( array(
1734 'user_id' => $user_id,
1735 'wpas-mr-message' => 'failed'
1736 ), admin_url( 'user-edit.php' ) );
1737 } else {
1738 delete_user_option( $user_id, 'mr_user_not_activated' );
1739
1740 // Notify to user
1741 $user = get_user_by( 'id', $user_id );
1742 $user_notify = new WPAS_User_Email_Notification( $user_id, $user->user_email );
1743 $user_notify->notify( 'moderated_registration_approved_user' );
1744
1745 $redirect_to = add_query_arg( array(
1746 'user_id' => $user_id,
1747 'wpas-mr-message' => 'success'
1748 ), admin_url( 'user-edit.php' ) );
1749 }
1750
1751 wpas_redirect( 'mr_activation', $redirect_to );
1752 }
1753
1754 }
1755
1756 add_action( 'wpas_do_mr_deny_user', 'wpas_do_mr_deny_user' );
1757
1758 /**
1759 * Deny moderated user registration
1760 *
1761 * @param array $data
1762 */
1763 function wpas_do_mr_deny_user( $data ) {
1764
1765 $user_id = $data['user_id'];
1766
1767 if( $user_id ) {
1768
1769 if ( ! current_user_can( 'edit_users' ) ) {
1770 wp_die( __( 'You do not have permission to deny users.', 'awesome-support' ), 403 );
1771 }
1772
1773 if ( ! current_user_can( 'edit_user', $user_id ) ) {
1774 wp_die( __( 'You do not have permission to edit this user.', 'awesome-support' ), 403 );
1775 }
1776
1777 update_user_option( $user_id, 'mr_user_denied', 'yes' );
1778
1779 // Notify to user
1780 $user = get_user_by( 'id', $user_id );
1781 $user_notify = new WPAS_User_Email_Notification( $user_id, $user->user_email );
1782 $user_notify->notify( 'moderated_registration_denied_user' );
1783
1784 $redirect_to = add_query_arg( array(
1785 'user_id' => $user_id,
1786 'wpas-mr-deny-message' => 'success'
1787 ), admin_url( 'user-edit.php' ) );
1788
1789
1790 wpas_redirect( 'mr_activation', $redirect_to );
1791 }
1792 }
1793
1794
1795 add_action( 'admin_init', 'wpas_mr_activation_notices', 10, 0 );
1796
1797 /**
1798 * Register moderated user activation notices
1799 */
1800 function wpas_mr_activation_notices() {
1801
1802 if ( isset( $_GET['wpas-mr-message'] ) ) {
1803
1804 $_SERVER['REQUEST_URI'] = remove_query_arg( 'wpas-mr-message' );
1805
1806 if ( 'success' === $_GET['wpas-mr-message'] ) {
1807 add_action( 'admin_notices', 'wpas_mr_activation_success_notice' );
1808 } else {
1809 add_action( 'admin_notices', 'wpas_mr_activation_failed_notice' );
1810 }
1811
1812 } elseif ( isset( $_GET['wpas-mr-deny-message'] ) ) {
1813
1814 $_SERVER['REQUEST_URI'] = remove_query_arg( 'wpas-mr-deny-message' );
1815
1816 if ( 'success' === $_GET['wpas-mr-deny-message'] ) {
1817 add_action( 'admin_notices', 'wpas_mr_deny_success_notice' );
1818 }
1819
1820 }
1821 }
1822
1823 /**
1824 * Print notice once a moderated user successfully activated
1825 */
1826 function wpas_mr_activation_success_notice() {
1827
1828 printf( '<div class="updated"><p>%s</p></div>', esc_html__( 'User successfully activated.', 'awesome-support' ) );
1829
1830 }
1831
1832 /**
1833 * Print notice once a moderated user activation failed
1834 */
1835 function wpas_mr_activation_failed_notice() {
1836
1837 printf( '<div class="updated error"><p>%s</p></div>', esc_html__( 'Error while activating user, try again later.', 'awesome-support' ) );
1838
1839 }
1840
1841 /**
1842 * Print notice once a moderated user registration denied
1843 */
1844 function wpas_mr_deny_success_notice() {
1845
1846 printf( '<div class="updated error"><p>%s</p></div>', esc_html__( 'User successfully denied.', 'awesome-support' ) );
1847
1848 }
1849
1850 /**
1851 * Takes a one dimensional array of user ids and returns an array of user objects
1852 */
1853 function wpas_id_to_user_object( $user_ids ) {
1854 $user_objects = array();
1855 foreach ($user_ids as $id) {
1856 $user_objects[] = get_user_by('id', $id);
1857 }
1858 return $user_objects;
1859 }
1860 /**
1861 * Temporarily save Registration Form fields before validation
1862 * This will help user NOT to retype registration fields
1863 *
1864 * @param array $user User object
1865 * @param string $redirect_to Redirect to URL
1866 * @param array $data HTTP Request data
1867 */
1868 function wpas_pre_register_temp_value_save( $user, $redirect_to, $data )
1869 {
1870 if ( isset( $user["first_name"] ) && $user["first_name"] ) {
1871 $_SESSION["wpas_registration_form"]["first_name"] = $user["first_name"];
1872 }
1873 if ( isset( $user["last_name"] ) && $user["last_name"] ) {
1874 $_SESSION["wpas_registration_form"]["last_name"] = $user["last_name"];
1875 }
1876 if ( isset($user["email"] ) && $user["email"] ) {
1877 $_SESSION["wpas_registration_form"]["email"] = $user["email"];
1878 }
1879 }
1880 add_action( "wpas_pre_register_account", "wpas_pre_register_temp_value_save", 10, 3 );
1881
1882 /**
1883 * Clear temporary $_SESSION variables once registration form values are displayed in relative fields.
1884 */
1885 function wpas_after_registration_clean_temp() {
1886 unset( $_SESSION["wpas_registration_form"] );
1887 }
1888 add_action( "wpas_after_registration_fields", "wpas_after_registration_clean_temp", 10 );
1889