/** * Success callback for social networks authentication * @param $client * @throws ErrorException * @throws \yii\base\ExitException */ public function successCallback($client) { $model = AuthClientHelper::findUserByService($client); if (is_object($model) === false) { // user not found, retrieve additional data $client = AuthClientHelper::retrieveAdditionalData($client); $attributes = AuthClientHelper::mapUserAttributesWithService($client); // check if it is anonymous user if (Yii::$app->user->isGuest === true) { $model = new User(['scenario' => 'registerService']); $security = Yii::$app->security; $model->setAttributes($attributes['user']); $model->status = User::STATUS_ACTIVE; if (empty($model->username) === true) { // if we doesn't have username - generate unique random temporary username // it will be needed for saving purposes $model->username = $security->generateRandomString(18); $model->username_is_temporary = 1; } $model->setPassword($security->generateRandomString(16)); $model->generateAuthKey(); if ($model->save() === false) { if (isset($model->errors['username'])) { // regenerate username $model->username = $security->generateRandomString(18); $model->username_is_temporary = 1; $model->save(); } if (isset($model->errors['email'])) { // empty email $model->email = null; $model->save(); } if (count($model->errors) > 0) { throw new ErrorException(Yii::t('app', "Temporary error signing up user")); } } } else { // non anonymous - link to existing account /** @var \app\modules\user\models\User $model */ $model = Yii::$app->user->identity; } $service = new UserService(); $service->service_type = $client->className(); $service->service_id = '' . $attributes['service']['service_id']; $service->user_id = $model->id; if ($service->save() === false) { throw new ErrorException(Yii::t('app', "Temporary error saving social service")); } } elseif (Yii::$app->user->isGuest === false) { // service exists and user logged in // check if this service is binded to current user if ($model->id != Yii::$app->user->id) { throw new ErrorException(Yii::t('app', "This service is already binded to another user")); } else { throw new ErrorException(Yii::t('app', 'This service is already binded.')); } } TagDependency::invalidate(Yii::$app->cache, ['Session:' . Yii::$app->session->id]); Yii::$app->user->login($model, 86400); if ($model->username_is_temporary == 1 || empty($model->email)) { // show post-registration form $this->layout = $this->module->postRegistrationLayout; $model->setScenario('completeRegistration'); echo $this->render('post-registration', ['model' => $model]); Yii::$app->end(); return; } }