You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							314 lines
						
					
					
						
							9.0 KiB
						
					
					
				
			
		
		
	
	
							314 lines
						
					
					
						
							9.0 KiB
						
					
					
				| <?php | |
|  | |
| namespace core\entities\user; | |
|  | |
| use core\entities\Session; | |
| use core\events\EventTrait; | |
| use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior; | |
| use core\AggregateRoot; | |
| use core\events\user\UserSignUpConfirmed; | |
| use core\events\user\UserSignUpRequested; | |
| use Yii; | |
| use yii\behaviors\TimestampBehavior; | |
| use yii\db\ActiveQuery; | |
| use yii\db\ActiveRecord; | |
| use zertex\avatar_generator\AvatarGenerator; | |
|  | |
| /** | |
|  * User model | |
|  * | |
|  * @property integer $id | |
|  * @property string $username | |
|  * @property string $password_hash | |
|  * @property string $password_reset_token | |
|  * @property string $email | |
|  * @property string $email_confirm_token | |
|  * @property string $auth_key | |
|  * @property integer $status | |
|  * @property integer $created_at | |
|  * @property integer $updated_at | |
|  * @property string $user_pic | |
|  * @property string $backend_language | |
|  * @property string $frontend_language | |
|  * @property string $settings | |
|  * @property string $password write-only password | |
|  * | |
|  * @property Network[] $networks | |
|  */ | |
| class User extends ActiveRecord implements AggregateRoot | |
| { | |
|     use EventTrait; | |
|  | |
|     const STATUS_WAIT = 0; | |
|     const STATUS_ACTIVE = 10; | |
|  | |
|     public static function create(string $username, string $email, string $password): self | |
|     { | |
|         $user           = new User(); | |
|         $user->username = $username; | |
|         $user->email    = $email; | |
|         $user->setPassword(!empty($password) ? $password : Yii::$app->security->generateRandomString()); | |
|         $user->created_at = time(); | |
|         $user->status     = self::STATUS_ACTIVE; | |
|         $user->auth_key   = Yii::$app->security->generateRandomString(); | |
|  | |
|         if ($user->user_pic) { | |
|             $fileName = md5('avatar-' . $user->user_pic->baseName . time()) . '.' . $user->user_pic->extension; | |
|             if ($user->user_pic->saveAs((new AvatarGenerator())->getPath('avatar') . '/' . $fileName)) { | |
|                 $user->user_pic = $fileName; | |
|             } | |
|         } | |
|  | |
|         return $user; | |
|     } | |
|  | |
|     public function edit(string $username, string $email, string $password, $user_pic = null): void | |
|     { | |
|         $this->username   = $username; | |
|         $this->email      = $email; | |
|         $this->updated_at = time(); | |
|  | |
|         if ($user_pic) { | |
|             $fileName = md5('avatar-' . $user_pic->baseName . time()) . '.' . $user_pic->extension; | |
|             if ($user_pic->saveAs((new AvatarGenerator())->getPath('avatar') . '/' . $fileName)) { | |
|                 (new AvatarGenerator())->remove('avatar', $this->user_pic); | |
|                 $this->user_pic = $fileName; | |
|             } | |
|         } | |
|  | |
|         if ($password) { | |
|             $this->setPassword(!empty($password) ? $password : Yii::$app->security->generateRandomString()); | |
|             $this->generateAuthKey(); | |
|             Session::deleteAll(['user_id' => $this->id]); | |
|         } | |
|     } | |
|  | |
|     public function editProfile( | |
|         string $email, | |
|         string $username, | |
|         string $password = null, | |
|         $user_pic = null, | |
|         $language | |
|     ): void { | |
|         $this->email    = $email; | |
|         $this->username = $username; | |
|         if ($password && !empty($password)) { | |
|             $this->setPassword($password); | |
|         } | |
|         $this->updated_at       = time(); | |
|         $this->backend_language = $language; | |
|  | |
|         /* @var $user_pic \yii\web\UploadedFile */ | |
|         if ($user_pic) { | |
|             $fileName = md5('avatar-' . $user_pic->baseName . time()) . '.' . $user_pic->extension; | |
|             $path     = Yii::getAlias('@runtime/' . $fileName); | |
|             $user_pic->saveAs($path); | |
|             $this->user_pic = basename(Yii::$app->avatar->update($username, null, $path)); | |
|             if (file_exists($path)) { | |
|                 unlink($path); | |
|             } | |
|         } | |
|     } | |
|  | |
|     public static function requestSignup(string $username, string $email, string $password): self | |
|     { | |
|         $user           = new User(); | |
|         $user->username = $username; | |
|         $user->email    = $email; | |
|         $user->setPassword($password); | |
|         $user->created_at          = time(); | |
|         $user->status              = self::STATUS_WAIT; | |
|         $user->email_confirm_token = Yii::$app->security->generateRandomString(); | |
|         $user->generateAuthKey(); | |
|         $user->recordEvent(new UserSignUpRequested($user)); | |
|  | |
|         return $user; | |
|     } | |
|  | |
|     public function confirmSignup(): void | |
|     { | |
|         if (!$this->isWait()) { | |
|             throw new \DomainException('User is already active.'); | |
|         } | |
|         $this->status              = self::STATUS_ACTIVE; | |
|         $this->email_confirm_token = null; | |
|         $this->recordEvent(new UserSignUpConfirmed($this)); | |
|     } | |
|  | |
|     public static function signupByNetwork($network, $identity): self | |
|     { | |
|         $user             = new User(); | |
|         $user->created_at = time(); | |
|         $user->status     = self::STATUS_ACTIVE; | |
|         $user->generateAuthKey(); | |
|         $user->networks = [Network::create($network, $identity)]; | |
|  | |
|         return $user; | |
|     } | |
|  | |
|     public function attachNetwork($network, $identity): void | |
|     { | |
|         $networks = $this->networks; | |
|         foreach ($networks as $current) { | |
|             if ($current->isFor($network, $identity)) { | |
|                 throw new \DomainException('Network is already attached.'); | |
|             } | |
|         } | |
|         $networks[]     = Network::create($network, $identity); | |
|         $this->networks = $networks; | |
|     } | |
|  | |
|  | |
|     public function requestPasswordReset(): void | |
|     { | |
|         if (!empty($this->password_reset_token) && self::isPasswordResetTokenValid($this->password_reset_token)) { | |
|             throw new \DomainException(Yii::t('auth', 'Password resetting is already requested.')); | |
|         } | |
|         $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); | |
|     } | |
|  | |
|     public function resetPassword($password): void | |
|     { | |
|         if (empty($this->password_reset_token)) { | |
|             throw new \DomainException(Yii::t('auth', 'Password resetting is not requested.')); | |
|         } | |
|         $this->setPassword($password); | |
|         $this->password_reset_token = null; | |
|     } | |
|  | |
|     public function isWait(): bool | |
|     { | |
|         return $this->status === self::STATUS_WAIT; | |
|     } | |
|  | |
|     public function isActive(): bool | |
|     { | |
|         return $this->status === self::STATUS_ACTIVE; | |
|     } | |
|  | |
|     public function getNetworks(): ActiveQuery | |
|     { | |
|         return $this->hasMany(Network::class, ['user_id' => 'id']); | |
|     } | |
|  | |
|     /** | |
|      * @inheritdoc | |
|      */ | |
|     public static function tableName() | |
|     { | |
|         return '{{%users}}'; | |
|     } | |
|  | |
|     /** | |
|      * @inheritdoc | |
|      */ | |
|     public function behaviors() | |
|     { | |
|         return [ | |
|             TimestampBehavior::class, | |
|             [ | |
|                 'class'     => SaveRelationsBehavior::class, | |
|                 'relations' => ['networks'], | |
|             ], | |
|         ]; | |
|     } | |
|  | |
|     public function transactions() | |
|     { | |
|         return [ | |
|             self::SCENARIO_DEFAULT => self::OP_ALL, | |
|         ]; | |
|     } | |
|  | |
|     /** | |
|      * Finds user by username | |
|      * | |
|      * @param string $username | |
|      * | |
|      * @return static|null | |
|      */ | |
|     public static function findByUsername($username) | |
|     { | |
|         return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); | |
|     } | |
|  | |
|     /** | |
|      * Finds user by password reset token | |
|      * | |
|      * @param string $token password reset token | |
|      * | |
|      * @return static|null | |
|      */ | |
|     public static function findByPasswordResetToken($token) | |
|     { | |
|         if (!static::isPasswordResetTokenValid($token)) { | |
|             return null; | |
|         } | |
|  | |
|         return static::findOne([ | |
|             'password_reset_token' => $token, | |
|             'status'               => self::STATUS_ACTIVE, | |
|         ]); | |
|     } | |
|  | |
|     /** | |
|      * Finds out if password reset token is valid | |
|      * | |
|      * @param string $token password reset token | |
|      * | |
|      * @return bool | |
|      */ | |
|     public static function isPasswordResetTokenValid($token) | |
|     { | |
|         if (empty($token)) { | |
|             return false; | |
|         } | |
|  | |
|         $timestamp = (int)substr($token, strrpos($token, '_') + 1); | |
|         $expire    = Yii::$app->params['user.passwordResetTokenExpire']; | |
|  | |
|         return $timestamp + $expire >= time(); | |
|     } | |
|  | |
|     /** | |
|      * Validates password | |
|      * | |
|      * @param string $password password to validate | |
|      * | |
|      * @return bool if password provided is valid for current user | |
|      */ | |
|     public function validatePassword($password) | |
|     { | |
|         return Yii::$app->security->validatePassword($password, $this->password_hash); | |
|     } | |
|  | |
|     /** | |
|      * @param $password | |
|      * | |
|      * @throws \yii\base\Exception | |
|      */ | |
|     private function setPassword($password) | |
|     { | |
|         $this->password_hash = Yii::$app->security->generatePasswordHash($password); | |
|     } | |
|  | |
|     /** | |
|      * Generates "remember me" authentication key | |
|      */ | |
|     private function generateAuthKey() | |
|     { | |
|         $this->auth_key = Yii::$app->security->generateRandomString(); | |
|     } | |
|  | |
|     public function attributeLabels() | |
|     { | |
|         return [ | |
|             'id'         => Yii::t('user', 'ID'), | |
|             'username'   => Yii::t('user', 'Username'), | |
|             'email'      => Yii::t('user', 'E-mail'), | |
|             'status'     => Yii::t('user', 'Status'), | |
|             'created_at' => Yii::t('user', 'Created At'), | |
|             'updated_at' => Yii::t('user', 'Updated At'), | |
|         ]; | |
|     } | |
| }
 | |
| 
 |