Register > Social * @copyright Tamaranga */ class Social extends AuthForm { public function init() { parent::init(); $this->setTemplate('register/social', 'users'); } public function data() { if ($this->request->user()) { return Users::redirectToAccountSettings(); } $data = $this->socialData(); # Данные о процессе регистрации через соц.сеть некорректны, причины: # 1) не удалось сохранить в сессии # 2) повторная попытка, вслед за успешной (случайный переход по ссылке) if (empty($data)) { return Redirect::to($this->registrationUrl('start')); } # Default user avatar if (empty($data['avatar'])) { $data['avatar'] = UsersAvatar::url(0, ''); } $data['phone_on'] = $this->phoneOnly() || $this->phoneAndEmail(); $data['agreement_on'] = $this->hasAgreement(); $data['agreement_url'] = Users::url('agreement'); $data['login_url'] = $this->loginUrl(); $data['forgot_url'] = $this->forgotUrl(['social' => 1]); $data['site_title'] = Site::title('users.register.social'); $data['title'] = _t('users', 'Registration via social network'); return $data; } public function socialData() { return Users::social()->authData() ?: []; } public function validate($data = []) { $data = $this->validateUsingRules($data, [ 'email' => [TYPE_NOTAGS, 'limit' => 100], 'phone_number' => [TYPE_NOTAGS, 'limit' => 30], 'agreement' => [TYPE_BOOL], ]); do { # Email if (! empty($data['email'])) { if (! $this->validateEmail($data['email'])) { break; } if ($this->isEmailExists($data['email'])) { $this->respond('exists', true); break; } } else { unset($data['email']); } # Phone if (mb_strlen($data['phone_number']) > 4) { if (! $this->validatePhone($data['phone_number'])) { break; } if ($this->isPhoneExists($data['phone_number'])) { $this->respond('exists', true); break; } } else { unset($data['phone_number']); } # Agreement if (! $this->validateAgreement($data['agreement'])) { break; } unset($data['agreement']); } while (false); # Blocks validation if ($this->errors->no()) { $data = $this->validateBlocks($data); } return $data; } public function submit() { # User account exists => switch to "Login" flow $this->respond('exists', false); if ($this->request->user()) { # User already logined $this->errors->reloadPage(); return parent::submit(); } do { # Request if (!$this->security->validateReferer()) { $this->errors->reloadPage(); break; } # Social data $social = $this->socialData(); if (empty($social)) { # No social data (something went wrong) $this->errors->reloadPage(); break; } # Fields validation $data = $this->validate(); if ($this->errors->any()) { break; } # User account already exists (email or phone exists) if ($this->respond('exists')) { # Switch to "Login" flow break; } $data['name'] = $social['name'] ?? ''; # Name from social network $email = $data['email'] ?? ''; $phone = $data['phone_number'] ?? ''; # Create new user account + generate password $user = Users::userRegister($data); if (empty($user)) { $this->errors->set(_t('users', 'Registration error, contact the administrator')); break; } $userId = $user['user_id']; # Upload social account avatar if (! empty($social['avatar'])) { Users::avatar($userId)->uploadSocial($social['provider_id'], $social['avatar'], true); } # Link social account to user account Users::social()->authFinish($userId); # Activate user account without email confirmation if ($this->skipEmailConfirmation()) { # Activate if (! Users::userActivate($userId)) { $this->errors->reloadPage(); break; } # Authenticate if (Users::authById($userId) !== true) { $this->errors->reloadPage(); break; } # Send success registration notification if ($email) { Users::sendAutoRegistrationNotification($userId, $data['name'], $email, $user['password']); } # Redirect to next step $this->respond('redirect', $this->registrationUrl('finished')); break; } # Send code (sms) if ($phone) { $activation = Users::getActivationInfo(); if (Users::sms()->sendActivationCode($phone, $activation['key'])) { Users::updateActivationKey($userId, $activation['key']); # Save data for next step $this->startData([ 'id' => $userId, 'password' => $user['password'], ]); # Redirect to "Phone confirmation" step $this->respond('redirect', $this->registrationUrl('phone')); } else { # Unable to send activation code (try again) $this->errors->reloadPage(); } break; } # Send email confirmation notification if ($email) { Users::sendEmailRegistrationConfirmation($userId, $email, $user['password'], $user['activate_link']); # Save data for next step $this->startData([ 'id' => $userId, 'password' => $user['password'], 'activate_link' => $user['activate_link'], ]); # Redirect to next step $this->respond('redirect', $this->registrationUrl('emailed')); break; } # Phone or Email is required if ($this->phoneOnly() || $this->phoneAndEmail()) { $this->errors->set(_t('users', 'Enter your phone or email')); } elseif ($this->emailOnly()) { $this->errors->set(_t('users', 'Enter email')); } else { # Unknown step (something went wrong) $this->errors->impossible(); } } while (false); return parent::submit(); } public function skipEmailConfirmation() { return ! $this->config('users.register.social.email.activation', true, TYPE_BOOL); } }