password_hash_strategy; } switch ($passwordHashStrategy) { case self::PASS_HASH_STRATEGY_OLD_ELY: return UserPass::make($this->email, $password) === $this->password_hash; case self::PASS_HASH_STRATEGY_YII2: return Yii::$app->security->validatePassword($password, $this->password_hash); default: throw new InvalidConfigException('You must set valid password_hash_strategy before you can validate password'); } } public function setPassword(string $password): void { $this->password_hash_strategy = self::PASS_HASH_STRATEGY_YII2; $this->password_hash = Yii::$app->security->generatePasswordHash($password); $this->password_changed_at = time(); } public function getEmailActivations(): EmailActivationQuery { return $this->hasMany(EmailActivation::class, ['account_id' => 'id']); } public function getOauthSessions(): ActiveQuery { return $this->hasMany(OauthSession::class, ['account_id' => 'id']); } public function getOauthClients(): OauthClientQuery { /** @noinspection PhpIncompatibleReturnTypeInspection */ return $this->hasMany(OauthClient::class, ['account_id' => 'id']); } public function getUsernameHistory(): ActiveQuery { return $this->hasMany(UsernameHistory::class, ['account_id' => 'id']); } public function getSessions(): ActiveQuery { return $this->hasMany(AccountSession::class, ['account_id' => 'id']); } public function getMinecraftAccessKeys(): ActiveQuery { return $this->hasMany(MinecraftAccessKey::class, ['account_id' => 'id']); } public function hasMojangUsernameCollision(): bool { return MojangUsername::find() ->andWhere(['username' => $this->username]) ->exists(); } /** * Since we don't have info about the user's static_url, we still generate the simplest * version with a link to the profile by it's id. On Ely.by, it will be redirected to static url. * * @return string */ public function getProfileLink(): string { return 'http://ely.by/u' . $this->id; } /** * Initially, the table of users we got from the main site, where there were no rules. * All existing users at the time of migration received an empty value in this field. * They will have to confirm their agreement with the rules at the first login. * All new users automatically agree with the current version of the rules. * * @return bool */ public function isAgreedWithActualRules(): bool { return $this->rules_agreement_version === LATEST_RULES_VERSION; } public function setRegistrationIp($ip): void { $this->registration_ip = $ip === null ? null : inet_pton($ip); } public function getRegistrationIp(): ?string { return $this->registration_ip === null ? null : inet_ntop($this->registration_ip); } public function getDeleteAt(): Carbon { Assert::notNull($this->deleted_at, 'This method should not be called on not deleted records'); return Carbon::createFromTimestamp($this->deleted_at)->add(new DateInterval(Account::ACCOUNT_DELETION_DELAY)); } public function afterSave($insert, $changedAttributes): void { parent::afterSave($insert, $changedAttributes); if ($insert) { return; } $meaningfulFields = ['username', 'email', 'uuid', 'status', 'lang', 'deleted_at']; $meaningfulChangedAttributes = array_filter( $changedAttributes, fn(string $key): bool => in_array($key, $meaningfulFields, true), ARRAY_FILTER_USE_KEY, ); if (empty($meaningfulChangedAttributes)) { return; } $notification = new AccountEditNotification($this, $meaningfulChangedAttributes); Yii::$app->queue->push(new CreateWebHooksDeliveries($notification)); } public function afterDelete(): void { parent::afterDelete(); if ($this->status !== self::STATUS_REGISTERED) { Yii::$app->queue->push(new CreateWebHooksDeliveries(new AccountDeletedNotification($this))); } } }