PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / trunk
Fluent Support – Helpdesk & Customer Support Ticket System vtrunk
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / app / Http / Controllers / AuthController.php

AuthController.php in Fluent Support – Helpdesk & Customer Support Ticket System trunk, at app/Http/Controllers/AuthController.php

815 lines 28.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Controllers;
4
5 use FluentSupport\App\Models\Meta;
6 use FluentSupport\App\Services\Helper;
7 use FluentSupport\Framework\Support\Arr;
8 use FluentSupport\Framework\Http\Request\Request;
9 use FluentSupport\App\Hooks\Handlers\AuthHandler;
10 use FluentSupport\App\Hooks\Handlers\ReCaptchaHandler;
11 use FluentSupport\App\Hooks\Handlers\TwoFaHandler;
12 use FluentSupport\App\Hooks\Handlers\EmailVerificationHandler;
13
14
15 class AuthController extends Controller
16 {
17 /**
18 * signUp method will create new user submitted data from sign up form
19 * @param Request $request
20 * @return \WP_REST_Response
21 * @throws \FluentSupport\Framework\Validator\ValidationException
22 */
23 public function signup(Request $request)
24 {
25
26 if(Helper::getAuthProvider() !== 'fluent_support') {
27 return $this->sendError([
28 'message' => __('You are not allowed to signup using this form', 'fluent-support')
29 ]);
30 }
31
32 if (!wp_verify_nonce($request->getSafe('_fsupport_signup_nonce', 'sanitize_text_field'), 'fluent_support_signup_nonce')) {
33 return $this->sendError([
34 'message' => __('Security verification failed. Please try again', 'fluent-support')
35 ]);
36 }
37
38 $fields = AuthHandler::getSignupFields();
39
40 $rules = $this->getRules($fields);
41
42 $messages = $this->getMessages($rules);
43
44 /*
45 * Filter user signup form data
46 *
47 * @since v1.0.0
48 * @param array $formData
49 */
50 $formData = apply_filters('fluent_support/signup_form_data', $request->all());
51
52 /*
53 * Action before validate user signup
54 *
55 * @since v1.0.0
56 * @param array $formData
57 */
58 do_action('fluent_support/before_signup_validation', $formData);
59
60 // the verification code is only submitted on the second step, after the customer has
61 // already passed the captcha and received the email; that step validates the hash
62 // against an issued record below, so the captcha can be skipped there. The first
63 // submit (which sends the verification email) always has to pass the captcha.
64 $isVerificationStep = !empty($formData['_email_verification_token']);
65
66 $checkRecaptchaAvailability = ReCaptchaHandler::isRecaptchaApplicable('signup_form');
67 if ($checkRecaptchaAvailability && !$isVerificationStep) {
68 $validateCaptcha = ReCaptchaHandler::validateRecaptcha($formData['g-recaptcha-response'] ?? '', null, null, 'signup');
69 if (!$validateCaptcha) {
70 return $this->response([
71 'message' => __('Your recaptcha is not verified', 'fluent-support')
72 ], 422);
73 }
74 }
75
76 $this->validate($formData, $rules, $messages);
77
78 if (!$isVerificationStep) {
79 $tokenHtml = EmailVerificationHandler::sendSignupEmailVerificationHtml($formData);
80
81 return $this->response([
82 'verification_html' => $tokenHtml
83 ]);
84 } else {
85 $token = $formData['_email_verification_token'];
86 $verificationHash = $formData['_email_verification_hash'] ?? '';
87
88 $logHashMeta = Meta::where('object_type', 'fs_login_hashes',)
89 ->where('key', $verificationHash)
90 ->first();
91
92 if (!$logHashMeta) {
93 wp_send_json([
94 'message' => __('Please provide a valid verification code that was sent to your email address', 'fluent-support')
95 ], 422);
96 }
97
98 $logHash = Helper::safeUnserialize($logHashMeta->value);
99
100 if (!$logHash) {
101 wp_send_json([
102 'message' => __('Please provide a valid verification code that was sent to your email address', 'fluent-support')
103 ], 422);
104 }
105
106 // the code must still be unused and must not have been consumed by a prior request
107 if (($logHash['status'] ?? '') !== 'issued') {
108 wp_send_json([
109 'message' => __('Your verification code has already been used. Please try again', 'fluent-support')
110 ], 422);
111 }
112
113 // records created before the email-binding fix (or any other legacy/malformed record)
114 // have no bound email; treat them as invalid rather than proceeding with a null email
115 if (empty($logHash['email'])) {
116 wp_send_json([
117 'message' => __('Your verification code has expired. Please request a new one', 'fluent-support')
118 ], 422);
119 }
120
121 // check if it got expired or not
122 // valid_till is written via gmdate() on a current_time('timestamp') basis (always
123 // UTC-equivalent, since WP resets the runtime timezone to UTC on every request), so
124 // it must be parsed back as UTC here - otherwise strtotime() would silently reinterpret
125 // it under whatever timezone a plugin/theme may have switched to via
126 // date_default_timezone_set() without restoring it, causing false expiry (or non-expiry)
127 $validTill = $logHash['valid_till'] ?? '';
128 if (($logHash['used_count'] ?? 0) > 5 || ($validTill && strtotime($validTill . ' UTC') < current_time('timestamp'))) {
129 wp_send_json([
130 'message' => __('Your verification code has been expired. Please try again', 'fluent-support')
131 ], 422);
132 }
133
134 if (!wp_check_password($token, $logHash['two_fa_code_hash'])) {
135
136 $logHash['used_count'] += 1;
137 Meta::where('key', $logHash['login_hash'])->update([
138 'value' => maybe_serialize($logHash)
139 ]);
140
141 wp_send_json([
142 'message' => __('Please provide a valid verification code that was sent to your email address', 'fluent-support')
143 ], 422);
144 }
145
146 // atomically consume the code: only succeeds if the record is still in the exact
147 // state we just read, closing the race where two requests both pass the checks above
148 $consumed = Meta::where('key', $logHash['login_hash'])
149 ->where('object_type', 'fs_login_hashes')
150 ->where('value', $logHashMeta->value)
151 ->update([
152 'value' => maybe_serialize(array_merge($logHash, [
153 'used_count' => ($logHash['used_count'] ?? 0) + 1,
154 'status' => 'used',
155 ]))
156 ]);
157
158 if (!$consumed) {
159 wp_send_json([
160 'message' => __('Your verification code has already been used. Please try again', 'fluent-support')
161 ], 422);
162 }
163
164 // the email is now server-verified for this code; ignore whatever the client
165 // submitted and use the address the code was actually issued to, so the signup
166 // can never be completed against a different (e.g. victim's) email address
167 $formData['email'] = $logHash['email'];
168 }
169
170 /*
171 * Action After validate user signup validation success
172 *
173 * @since v1.0.0
174 * @param array $formData
175 */
176 do_action('fluent_support/after_signup_validation', $formData);
177
178 $userId = $this->createUser($formData);
179
180 if (is_wp_error($userId)) {
181 return $this->response(
182 apply_filters(
183 'fluent_support/signup_create_user_error',
184 ['error' => $userId->get_error_message()]
185 ), 423);
186 }
187
188 /*
189 * Action After creating WP user from ticket sign up form
190 *
191 * @since v1.0.0
192 * @param array $formData
193 */
194 do_action('fluent_support/after_creating_user');
195
196 $this->maybeUpdateUser($userId, $formData);
197 $this->addUserMetaData($userId, $formData);
198 $this->assignRole($userId);
199 $this->login($userId);
200
201 /*
202 * Filter for user signup complete message and redirect
203 *
204 * @since v1.0.0
205 * @param array $response
206 */
207 $response = apply_filters('fluent_support/signup_complete_response', [
208 'message' => __('Successfully registered to the site.', 'fluent-support'),
209 'redirect' => Arr::get($formData, '__redirect_to', Helper::getPortalBaseUrl())
210 ]);
211
212 return $this->response($response);
213 }
214
215 /**
216 * handleLogin method will perform login functionality and redirect
217 * @param Request $request
218 * @return \WP_REST_Response
219 */
220 public function handleLogin(Request $request)
221 {
222 if(Helper::getAuthProvider() !== 'fluent_support') {
223 return $this->sendError([
224 'message' => __('You are not allowed to login using this form', 'fluent-support')
225 ]);
226 }
227
228 if (!wp_verify_nonce($request->getSafe('_support_login_nonce', 'sanitize_text_field'), 'fsupport_login_nonce')) {
229 return $this->response([
230 'message' => __('Security verification failed', 'fluent-support')
231 ], 403);
232 }
233
234 $data = $request->all();
235
236 $checkRecaptchaAvailability = ReCaptchaHandler::isRecaptchaApplicable('login_form');
237 if ($checkRecaptchaAvailability) {
238 $validateCaptcha = ReCaptchaHandler::validateRecaptcha($data['g-recaptcha-response'] ?? '', null, null, 'login');
239
240 if (!$validateCaptcha) {
241 return $this->response([
242 'message' => __('Your recaptcha is not verified', 'fluent-support')
243 ], 422);
244 }
245 }
246
247 if (empty($data['pwd']) || empty($data['log'])) {
248 return $this->response([
249 'message' => __('Email and Password is required', 'fluent-support')
250 ], 403);
251 }
252 $redirectUrl = Helper::getPortalBaseUrl();
253 if ($redirect = $request->getSafe('redirect_to', 'sanitize_text_field')) {
254 $redirectUrl = wp_validate_redirect($redirect, $redirectUrl);
255 }
256
257 if (get_current_user_id()) { // user already registered
258 return $this->sendSuccess([
259 'redirect' => $redirectUrl
260 ]);
261 }
262
263 $email = sanitize_user($data['log']);
264 $password = trim($data['pwd'] ?? '');
265
266 if (is_email($email)) {
267 $user = get_user_by('email', $email);
268 } else {
269 $user = get_user_by('login', $email);
270 }
271
272 // Rate limiting: per-IP bucket (5 attempts) + per-account bucket (20 attempts)
273 $ip = Helper::getIp();
274 $ipKey = $user
275 ? 'fs_login_ip_' . wp_hash($user->ID . '|' . $ip)
276 : 'fs_login_ip_' . wp_hash(strtolower($email) . '|' . $ip);
277 $accountKey = $user
278 ? 'fs_login_act_' . wp_hash($user->ID)
279 : 'fs_login_act_' . wp_hash(strtolower($email));
280
281 $ipAttempts = get_transient($ipKey);
282 $accountAttempts = get_transient($accountKey);
283
284 if (($ipAttempts !== false && $ipAttempts >= 5) || ($accountAttempts !== false && $accountAttempts >= 20)) {
285 return $this->sendError([
286 'message' => __('Too many login attempts. Please try again after 15 minutes.', 'fluent-support')
287 ], 429);
288 }
289
290 if (!$user) {
291 $user = new \WP_Error('authentication_failed', __('Invalid username, email address or incorrect password.', 'fluent-support'));
292
293 do_action('wp_login_failed', $email, $user);
294 $this->incrementLoginAttempts($ipKey);
295 $this->incrementLoginAttempts($accountKey);
296
297 return $this->response([
298 'message' => __('Email or Password is not valid. Please try again', 'fluent-support')
299 ], 403);
300
301 }
302
303 $twoFactorEnabled = Helper::getBusinessSettings('enable_two_fa');
304 if ('yes' === $twoFactorEnabled) {
305 if (!wp_check_password($password, $user->user_pass, $user->ID)) {
306 $this->incrementLoginAttempts($ipKey);
307 $this->incrementLoginAttempts($accountKey);
308
309 return $this->response([
310 'message' => __('Invalid username, email address or incorrect password.', 'fluent-support')
311 ], 403);
312 }
313
314 (new TwoFaHandler)->maybe2FaRedirect($user);
315 }
316
317 if (apply_filters('fluent_support_use_native_login', true)) {
318 $user = wp_signon();
319 if (is_wp_error($user)) {
320 $this->incrementLoginAttempts($ipKey);
321 $this->incrementLoginAttempts($accountKey);
322 return $this->response([
323 'message' => $user->get_error_message()
324 ], 403);
325 }
326
327 // Clear rate limits for the authenticated user
328 $authIpKey = 'fs_login_ip_' . wp_hash($user->ID . '|' . $ip);
329 $authAccountKey = 'fs_login_act_' . wp_hash($user->ID);
330 delete_transient($authIpKey);
331 delete_transient($authAccountKey);
332 return $this->sendSuccess([
333 'redirect' => $redirectUrl
334 ]);
335 }
336
337 if (wp_check_password($password, $user->user_pass, $user->ID)) {
338 delete_transient($ipKey);
339 delete_transient($accountKey);
340 $this->login($user->ID);
341 return $this->sendSuccess([
342 'redirect' => $redirectUrl
343 ]);
344 }
345
346 $this->incrementLoginAttempts($ipKey);
347 $this->incrementLoginAttempts($accountKey);
348
349 return $this->response([
350 'message' => __('Invalid username, email address or incorrect password.', 'fluent-support')
351 ], 403);
352 }
353
354 private function incrementLoginAttempts($rateLimitKey)
355 {
356 $attempts = get_transient($rateLimitKey);
357 if ($attempts === false) {
358 set_transient($rateLimitKey, 1, 15 * MINUTE_IN_SECONDS);
359 } else {
360 set_transient($rateLimitKey, $attempts + 1, 15 * MINUTE_IN_SECONDS);
361 }
362 }
363
364 private function nativeLoginHandler($user, $info, $redirectUrl = '')
365 {
366 if (!$redirectUrl) {
367 $redirectUrl = Helper::getPortalBaseUrl();
368 }
369
370 $secure_cookie = is_ssl();
371 if (!$secure_cookie && !force_ssl_admin()) {
372 if (get_user_option('use_ssl', $user->ID)) {
373 $secure_cookie = true;
374 force_ssl_admin(true);
375 }
376 }
377
378 if (class_exists('\Limit_Login_Attempts')) {
379 global $limit_login_attempts_obj;
380 $limit_login_attempts_try = $limit_login_attempts_obj->wp_authenticate_user($user, false);
381 if (is_wp_error($limit_login_attempts_try)) {
382 return $this->response([
383 'message' => implode('<br/>', $limit_login_attempts_try->get_error_messages())
384 ], 403);
385 }
386 }
387
388 $user_signon = wp_signon($info, $secure_cookie);
389
390 // Note: No sanitization needed here as we're only checking emptiness, not using the cookie value
391 if (!is_wp_error($user_signon) && empty($_COOKIE[LOGGED_IN_COOKIE])) {
392 if (headers_sent()) {
393 return $this->response([
394 // translators: %1$s is the URL to WordPress cookies documentation, %2$s is the URL to WordPress support forums
395 'message' => sprintf(__('<strong>ERROR</strong>: Cookies are blocked due to unexpected output. For help, please see <a href="%1$s">this documentation</a> or try the <a href="%2$s">support forums</a>.', 'fluent-support'),
396 'https://codex.wordpress.org/Cookies', 'https://wordpress.org/support/')
397 ], 403);
398 }
399 }
400
401 if (is_wp_error($user_signon)) {
402 $errorMessage = __('Email or Password is not valid. Please try again', 'fluent-support');
403
404 if (class_exists('Limit_Login_Attempts')) {
405 global $limit_login_attempts_obj;
406 if ($limit_login_attempts_obj) {
407 $limit_login_attempts_obj->limit_login_failed($user->user_login);
408 $msg = $limit_login_attempts_obj->get_message();
409 if ($msg) {
410 $errorMessage = $msg;
411 }
412 }
413 }
414
415 return $this->response([
416 'message' => $errorMessage
417 ], 403);
418 }
419
420 // WP Last Login plugin compatibility
421 if (class_exists('\Obenland_Wp_Last_Login')) {
422 update_user_meta($user_signon->ID, 'wp-last-login', time());
423 }
424
425 return $this->sendSuccess([
426 'redirect' => $redirectUrl
427 ]);
428 }
429
430 /**
431 * getRules method will prepare the rules for the input field
432 * @param array $fields
433 * @return mixed
434 */
435 protected function getRules($fields = [])
436 {
437 $rules = [];
438
439 foreach ($fields as $fieldName => $field) {
440 if (array_key_exists('required', $field)) {
441 $rules[$fieldName] = 'required';
442 }
443
444 $pipe = array_key_exists($fieldName, $rules) ? '|' : '';
445
446 if ($field['type'] === 'email') {
447 $rules[$fieldName] = $rules[$fieldName] . $pipe . 'email';
448 } elseif ($field['type'] === 'password') {
449 $rules[$fieldName] = $rules[$fieldName] . $pipe . 'min:8';
450 }
451 }
452 /*
453 * Filter user signup validation rules
454 *
455 * @since v1.0.0
456 * @param array $rules
457 */
458 return apply_filters('fluent_support/signup_validation_rules', $rules);
459 }
460
461
462 public function resetPassword(Request $request)
463 {
464
465 if(Helper::getAuthProvider() !== 'fluent_support') {
466 return $this->sendError([
467 'message' => __('You are not allowed to reset password using this form', 'fluent-support')
468 ]);
469 }
470
471 $errors = new \WP_Error();
472
473 if (!wp_verify_nonce($request->getSafe('_fsupport_reset_pass_nonce', 'sanitize_text_field'), 'fluent_support_reset_pass_nonce')) {
474 return $this->sendError([
475 'message' => __('Security verification failed. Please try again', 'fluent-support')
476 ]);
477 }
478
479 $usernameOrEmail = trim(wp_unslash($request->getSafe('user_login', 'sanitize_text_field')));
480
481 if (!$usernameOrEmail) {
482 return $this->sendError([
483 'message' => 'Username or email is required'
484 ]);
485 }
486
487 // IP bucket is a generous volumetric backstop (shared office/NAT IPs can have many
488 // unrelated users). It runs before the account lookup so that probes for accounts
489 // that don't exist are throttled too. Keyed on the IP only, so a 429 here reveals
490 // nothing about whether any given account exists.
491 if (Helper::hitRateLimit('fs_reset_pass_ip_' . wp_hash(Helper::getIp()), 20)) {
492 return $this->sendError([
493 'message' => __('Too many password reset requests. Please try again after 15 minutes.', 'fluent-support')
494 ], 429);
495 }
496
497 $user_data = get_user_by('email', $usernameOrEmail);
498
499 if (!$user_data) {
500 $user_data = get_user_by('login', $usernameOrEmail);
501 }
502
503 if (!$user_data) {
504 return $this->sendResetPassResponse();
505 }
506
507 $user_data = apply_filters('lostpassword_user_data', $user_data, $errors);
508
509 do_action('lostpassword_post', $errors, $user_data);
510
511 $errors = apply_filters('lostpassword_errors', $errors, $user_data);
512
513 if ($errors->has_errors()) {
514 return $this->sendResetPassResponse();
515 }
516
517 if (!$user_data) {
518 return $this->sendResetPassResponse();
519 }
520
521 if (is_multisite() && !is_user_member_of_blog($user_data->ID, get_current_blog_id())) {
522 return $this->sendResetPassResponse();
523 }
524
525 // Redefining user_login ensures we return the right case in the email.
526 $user_login = $user_data->user_login;
527
528 do_action('retrieve_password', $user_login);
529
530 $allow = apply_filters('allow_password_reset', true, $user_data->ID);
531
532 if (!$allow || is_wp_error($allow)) {
533 return $this->sendResetPassResponse();
534 }
535
536
537 /*
538 * Filter reset password link text
539 *
540 * @since v1.5.7
541 * @param string $linkText
542 */
543 // translators: %s is the site name
544 $linkText = apply_filters("fluent_support/reset_password_link", sprintf(__('Reset your password for %s', 'fluent-support'), get_bloginfo('name')));
545
546 // Issuance cooldown. get_password_reset_key() rotates the stored key, invalidating
547 // any link already sitting in the account owner's inbox, so an unthrottled caller
548 // could deny password recovery indefinitely. Suppressing the duplicate issuance is
549 // safe: reset mail only ever goes to the account owner, so whoever triggered the
550 // first send has already put a working link in that inbox.
551 $cooldownKey = 'fs_reset_pass_sent_' . wp_hash($user_data->ID);
552
553 if (get_transient($cooldownKey)) {
554 return $this->sendResetPassResponse();
555 }
556
557 set_transient($cooldownKey, 1, 5 * MINUTE_IN_SECONDS);
558
559 $resetUrl = add_query_arg([
560 'action' => 'rp',
561 'key' => get_password_reset_key($user_data),
562 'login' => rawurlencode($user_data->user_login)
563 ], wp_login_url());
564
565 $resetLink = '<a href="' . $resetUrl . '">' . $linkText . '</a>';
566
567 /*
568 * Filter reset password email subject
569 *
570 * @since v1.5.7
571 * @param string $mailSubject
572 */
573 // translators: %s is the site name
574 $mailSubject = apply_filters("fluent_support/reset_password_mail_subject", sprintf(__('Reset your password for %s support portal', 'fluent-support'), get_bloginfo('name')));
575
576 // translators: %s is the user's first name
577 $message = '<p>' . sprintf(__('Hi %s,', 'fluent-support'), $user_data->first_name) . '</p>' .
578 '<p>' . __('Someone has requested a new password for the following account on WordPress:', 'fluent-support') . '</p>' .
579 // translators: %s is the username
580 '<p>' . sprintf(__('Username: %s', 'fluent-support'), $user_login) . '</p>' .
581 '<p>' . $resetLink . '</p>' .
582 '<p>' . __('If you did not request to reset your password, please ignore this email.', 'fluent-support') . '</p>';
583
584 /*
585 * Filter reset password email body text
586 *
587 * @since v1.5.7
588 * @param string $message
589 * @param object $user
590 * @param string $resetLink
591 */
592 $message = apply_filters('fluent_support/reset_password_message', $message, $user_data, $resetLink);
593
594 $headers = array('Content-Type: text/html; charset=UTF-8');
595
596 wp_mail($user_data->user_email, $mailSubject, $message, $headers);
597
598 return $this->sendResetPassResponse();
599 }
600
601 /**
602 * Single response for every password reset outcome.
603 *
604 * Whether the account exists, is disallowed, is not a member of this site or is
605 * inside the resend cooldown, the caller sees the same thing — otherwise the form
606 * confirms which usernames and email addresses are real.
607 *
608 * @return mixed
609 */
610 protected function sendResetPassResponse()
611 {
612 return $this->sendSuccess([
613 'message' => __('If an account matches that username or email, a password reset link has been sent. Please check your inbox, including the spam folder.', 'fluent-support')
614 ]);
615 }
616
617 /**
618 * getMessages message will return the validation message regarding sign up or sign in
619 * @param array $rules
620 * @return mixed
621 */
622 protected function getMessages($rules = [])
623 {
624 /*
625 * Filter user signup validation message
626 *
627 * @since v1.0.0
628 * @param array $arg
629 * @param array $rules
630 */
631 return apply_filters('fluent_support/signup_validation_messages', [], $rules);
632 }
633
634 /**
635 * createUser method will create new user
636 * @param array $formData
637 * @return mixed
638 */
639 public function createUser($formData = [])
640 {
641 /*
642 * Filter user signup email
643 *
644 * @since v1.0.0
645 * @param string $email
646 */
647 $email = apply_filters('fluent_support/signup_email', Arr::get($formData, 'email'));
648
649 /*
650 * Filter user signup username
651 *
652 * @since v1.0.0
653 * @param string $username
654 */
655 $userName = apply_filters('fluent_support/signup_username', Arr::get($formData, 'username'));
656
657 if (empty($formData['password'])) {
658 $password = wp_generate_password(16, true, true);
659 } else {
660 $password = $formData['password'];
661 }
662
663 /*
664 * Filter user signup password
665 *
666 * @since v1.0.0
667 * @param string $password
668 */
669 $password = apply_filters('fluent_support/signup_password', $password);
670
671 /*
672 * Action before creating WP user using Fluent Support signup form
673 *
674 * @since v1.0.0
675 * @param string $userName
676 * @param string $password
677 * @param string $email
678 */
679 do_action('fluent_support/before_creating_user', $userName, $password, $email);
680
681 $userId = wp_create_user($userName, $password, $email);
682
683 if (is_wp_error($userId)) {
684 return false;
685 }
686
687 return $userId;
688
689 }
690
691 /**
692 * maybeUpdateUser method will update user information if exists
693 * @param $userId
694 * @param $formData
695 */
696 public function maybeUpdateUser($userId, $formData)
697 {
698 $firstName = Arr::get($formData, 'first_name', '');
699 $lastName = Arr::get($formData, 'last_name', '');
700 $name = trim($firstName . ' ' . $lastName);
701
702 $data = array_filter([
703 'ID' => $userId,
704 'user_nicename' => $name,
705 'display_name' => $name,
706 'first_name' => $firstName,
707 'last_name' => $lastName,
708 ]);
709
710 if ($name) {
711 /*
712 * Action before updating a customer/user
713 *
714 * @since v1.0.0
715 * @param array $data
716 */
717 do_action('fluent_support/before_updating_user', $data);
718
719 /*
720 * Filter user updatable data
721 *
722 * @since v1.0.0
723 * @param $data
724 */
725 $updateUserData = apply_filters('fluent_support/update_user_data', $data);
726 wp_update_user($updateUserData);
727
728 /*
729 * Action after updating a customer/user
730 *
731 * @since v1.0.0
732 * @param array $data
733 */
734 do_action('fluent_support/after_updating_user', $data);
735 }
736 }
737
738 public function addUserMetaData($userId, $formData) {
739 $customFieldsKey = apply_filters('fluent_support/custom_registration_form_fields_key', Helper::getBusinessSettings('custom_registration_form_field'));
740
741 if (empty($customFieldsKey)) {
742 return;
743 }
744
745 foreach ($customFieldsKey as $key) {
746 if (isset($formData[$key])) {
747 $fieldValue = $formData[$key];
748 update_user_meta($userId, $key, $fieldValue);
749 }
750 }
751 }
752
753 /**
754 * assignRole method will assign role to a given user id
755 * @param $userId
756 */
757 protected function assignRole($userId)
758 {
759 $user = new \WP_User($userId);
760
761 /*
762 * Action before assigning role to registered user
763 *
764 * @since v1.0.0
765 * @param array $data
766 */
767 do_action('fluent_support/before_assigning_role', $user);
768 /*
769 * Filter user assignable role after signup
770 *
771 * @since v1.0.0
772 * @param string $setRole WordPress user role key
773 */
774 $setRole = apply_filters('fluent_support/user_role', 'subscriber');
775 $user->set_role($setRole);
776
777 /*
778 * Action after assigning role to registered user
779 *
780 * @since v1.0.0
781 * @param array $data
782 */
783 do_action('fluent_support/after_assigning_role', $user);
784 }
785
786
787 /**
788 * login method will clear existing cookies and set new cookie for a given user id
789 * @param $userId
790 */
791 protected function login($userId)
792 {
793 /*
794 * Action before login
795 *
796 * @since v1.0.0
797 * @param integer $userId
798 */
799 do_action('fluent_support/before_logging_in_user', $userId);
800
801 wp_clear_auth_cookie();
802 wp_set_current_user($userId);
803 wp_set_auth_cookie($userId);
804
805 /*
806 * Action after login
807 *
808 * @since v1.0.0
809 * @param integer $userId
810 */
811 do_action('fluent_support/after_logging_in_user', $userId);
812 }
813
814 }
815