Yii::t('app', 'Почта уже занята')], [['username'], 'unique', 'message' => Yii::t('app', 'Логин уже занят')], [['email'], 'required'], [['role', 'email'], 'string'], ['status', 'in', 'range' => UserHelper::statusList()], ['type', 'in', 'range' => UserHelper::typeList()], ['role', 'in', 'range' => UserHelper::roleList()], [['agree', 'payment_bank'], 'safe'], ['role', 'required', 'on' => self::SCENARIO_USER_CREATE], [['employee', 'customer', 'admin'], 'safe'], ]; } public function behaviors(): array { return [ TimestampBehavior::class, [ 'class' => AttributeBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => 'username', ActiveRecord::EVENT_BEFORE_UPDATE => 'username', ], 'value' => function ($event) { return $this->email; }, ], ]; } public function afterSave($insert, $changedAttributes) { if ($insert) { if ($this->scenario === self::SCENARIO_USER_CREATE) { $this->trigger(self::EVENT_USER_CREATE); } //todo add scenario user status change } parent::afterSave($insert, $changedAttributes); } public function scenarios() { $scenarios = parent::scenarios(); $scenarios[self::SCENARIO_USER_CREATE] = ['type', 'status', 'email', 'agree', 'role']; $scenarios[self::SCENARIO_USER_ADMIN_UPDATE] = ['type', 'status', 'email', 'role', 'admin']; $scenarios[self::SCENARIO_USER_EMPLOYEE_UPDATE] = ['type', 'status', 'email', 'role', 'employee']; $scenarios[self::SCENARIO_USER_CUSTOMER_UPDATE] = ['type', 'status', 'email', 'role', 'customer']; return $scenarios; } public function attributeLabels(): array { return [ 'id' => Yii::t('user', 'ID'), 'email' => Yii::t('user', 'Email'), 'name' => Yii::t('user', 'Имя'), 'username' => Yii::t('user', 'Логин'), 'status' => Yii::t('user', 'Статус'), 'type' => Yii::t('user', 'Тип'), 'role' => Yii::t('user', 'Роль'), 'created_at' => Yii::t('user', 'Создан'), 'updated_at' => Yii::t('user', 'Обновлён'), ]; } public function setRole($role): void { if (!isset($role)) { throw new BadRequestHttpException(); } $auth = Yii::$app->authManager; $role = $auth->getRole($role); if ($role) { $auth->revokeAll($this->id); $auth->assign($role, $this->id); } } public function getRole() { $role = Yii::$app->authManager->getRolesByUser($this->id); if ($role) { return $role; } return false; } public function getTypeName(): string { return match ($this->type) { UserHelper::TYPE_CUSTOMER => 'customer', UserHelper::TYPE_EMPLOYEE => 'employee', UserHelper::TYPE_ADMIN => 'admin', }; } public function getUserAdmin(): ActiveQuery { return $this->hasOne(UserAdmin::class, ['user_id' => 'id']); } public function getUserCustomer(): ActiveQuery { return $this->hasOne(UserCustomer::class, ['user_id' => 'id']); } public function getUserEmployee(): ActiveQuery { return $this->hasOne(UserEmployee::class, ['user_id' => 'id']); } public function getMeta(): UserAdmin|UserEmployee|UserCustomer { return match ($this->type) { UserHelper::TYPE_ADMIN => $this->userAdmin, UserHelper::TYPE_EMPLOYEE => $this->userEmployee, default => $this->userCustomer, }; } static public function current(): User|IdentityInterface|null { return Yii::$app->user->identity; } public static function findIdentity($id): User|IdentityInterface|null { return static::findOne(['and', ['id' => $id], ['>=', 'status', UserHelper::STATUS_NEW], ] ); } public static function findIdentityByAccessToken($token, $type = null): ?IdentityInterface { //todo translate throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); } public static function findByUsername(string $email) { $user = User::find()->where(['and', ['or', ['email' => $email], ['username' => $email], ], ['>=', 'status', UserHelper::STATUS_NEW], ])->one(); return $user ?? null; } public static function findByPasswordResetToken($token): array|ActiveRecord|null { if (!static::isPasswordResetTokenValid($token)) { return null; } return static::find()->where(['and', ['password_reset_token' => $token], ['>=', 'status', UserHelper::STATUS_NEW], ])->one(); } public static function findByVerificationToken($token): array|ActiveRecord|null { return static::find()->where(['and', ['verification_token' => $token], ['>=', 'status', UserHelper::STATUS_NEW], ])->one(); } public static function isPasswordResetTokenValid($token): bool { if (empty($token)) { return false; } $timestamp = (int)substr($token, strrpos($token, '_') + 1); $expire = Yii::$app->params['user.passwordResetTokenExpire']; return $timestamp + $expire >= time(); } public function getId() { return $this->getPrimaryKey(); } public function getAuthKey(): ?string { return $this->auth_key; } public function validatePhone(string $phone): bool { return true; } public function validateAuthKey($authKey): bool { return $this->getAuthKey() === $authKey; } public function validatePassword(string $password): bool { return Yii::$app->security->validatePassword($password, $this->password_hash); } public function setPassword(string $password) { $this->password_hash = Yii::$app->security->generatePasswordHash($password); } public function generateAuthKey() { $this->auth_key = Yii::$app->security->generateRandomString(); } public function generatePasswordResetToken() { $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); } public function generateEmailVerificationToken() { $this->verification_token = Yii::$app->security->generateRandomString() . '_' . time(); } public function removePasswordResetToken() { $this->password_reset_token = null; } public function quizStart($count, $time): void { if (UserHelper::TYPE_EMPLOYEE == $this->type) { $user = UserEmployee::find()->where(['user_id' => $this->id])->one(); if ($user) { $user->test_try_count = $count; $user->test_at = $time; $user->test_result = null; $user->save(false); } } } public function quizFailed(): void { if (UserHelper::TYPE_EMPLOYEE == $this->type) { $this->status = UserHelper::STATUS_BLOCKED_AUTO; $this->save(false); } } public function setTestResult(bool $result): void { if (UserHelper::TYPE_EMPLOYEE == $this->type) { if ($result) { $this->status = UserHelper::STATUS_TEST; $this->save(false); } $this->meta->test_result = time(); $this->meta->save(false); } } public function testAt(): int|null { if (UserHelper::TYPE_EMPLOYEE == $this->type) { return $this->meta->test_at; } return null; } public function testTryCount(): int { if (UserHelper::TYPE_EMPLOYEE == $this->type) { return $this->meta->test_try_count ?? 0; } return 0; } public function getTestResult(): int|null { if (UserHelper::TYPE_EMPLOYEE == $this->type) { return $this->meta->test_result ?? null; } return null; } }