AdminUser.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. /**
  3. * Author: lf
  4. * Blog: https://blog.feehi.com
  5. * Email: job@feehi.com
  6. * Created at: 2017-03-15 21:16
  7. */
  8. namespace common\models;
  9. use Yii;
  10. use common\helpers\Util;
  11. use yii\base\NotSupportedException;
  12. use yii\behaviors\TimestampBehavior;
  13. use yii\web\ForbiddenHttpException;
  14. use yii\web\UploadedFile;
  15. /**
  16. * AdminUser model
  17. *
  18. * @property integer $id
  19. * @property string $username
  20. * @property string $password_hash
  21. * @property string $password_reset_token
  22. * @property string $email
  23. * @property string $auth_key
  24. * @property string $avatar
  25. * @property integer $status
  26. * @property integer $created_at
  27. * @property integer $updated_at
  28. * @property string $password write-only password
  29. */
  30. class AdminUser extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
  31. {
  32. const STATUS_DELETED = 0;
  33. const STATUS_ACTIVE = 10;
  34. public $password;
  35. public $repassword;
  36. public $old_password;
  37. /**
  38. * 返回数据表名
  39. *
  40. * @return string
  41. */
  42. public static function tableName()
  43. {
  44. return '{{%admin_user}}';
  45. }
  46. /**
  47. * @inheritdoc
  48. */
  49. public function rules()
  50. {
  51. return [
  52. [['username', 'password', 'repassword', 'password_hash'], 'string'],
  53. ['email', 'email'],
  54. ['email', 'unique'],
  55. [['repassword'], 'compare', 'compareAttribute' => 'password'],
  56. [['avatar'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg, jpeg, gif, webp'],
  57. [['status'], 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
  58. [['username', 'email', 'password', 'repassword'], 'required', 'on' => ['create']],
  59. [['username', 'email'], 'required', 'on' => ['update', 'self-update']],
  60. [['username'], 'unique', 'on' => 'create'],
  61. [['roles', 'permissions'], 'safe'],
  62. ];
  63. }
  64. public function behaviors()
  65. {
  66. return [
  67. TimestampBehavior::className(),
  68. ];
  69. }
  70. /**
  71. * @inheritdoc
  72. */
  73. public function scenarios()
  74. {
  75. return [
  76. 'default' => ['username', 'email'],
  77. 'create' => ['username', 'email', 'password', 'avatar', 'status', 'roles', 'permissions'],
  78. 'update' => ['username', 'email', 'password', 'avatar', 'status', 'roles', 'permissions'],
  79. 'self-update' => ['email', 'password', 'avatar', 'old_password', 'repassword'],
  80. ];
  81. }
  82. /**
  83. * @inheritdoc
  84. */
  85. public function attributeLabels()
  86. {
  87. return [
  88. 'username' => Yii::t('app', 'Username'),
  89. 'email' => Yii::t('app', 'Email'),
  90. 'old_password' => Yii::t('app', 'Old Password'),
  91. 'password' => Yii::t('app', 'Password'),
  92. 'repassword' => Yii::t('app', 'Repeat Password'),
  93. 'avatar' => Yii::t('app', 'Avatar'),
  94. 'status' => Yii::t('app', 'Status'),
  95. 'created_at' => Yii::t('app', 'Created At'),
  96. 'updated_at' => Yii::t('app', 'Updated At')
  97. ];
  98. }
  99. public function beforeValidate()
  100. {
  101. if($this->avatar !== "0") {//为0表示需要删除图片,Util::handleModelSingleFileUpload()会有判断删除图片
  102. $this->avatar = UploadedFile::getInstance($this, "avatar");
  103. }
  104. return parent::beforeValidate();
  105. }
  106. public function beforeSave($insert)
  107. {
  108. Util::handleModelSingleFileUpload($this, 'avatar', $insert, '@admin/uploads/avatar/');
  109. if ($insert) {
  110. $this->generateAuthKey();
  111. $this->setPassword($this->password);
  112. } else {//修改
  113. if( $this->getScenario() == "self-update" ){
  114. if ($this->password != '') {
  115. if ($this->old_password == '') {
  116. $this->addError('old_password', Yii::t('yii', '{attribute} cannot be blank.', ['attribute' => Yii::t('app', 'Old Password')]));
  117. return false;
  118. }
  119. if (! $this->validatePassword($this->old_password)) {
  120. $this->addError('old_password', Yii::t('app', '{attribute} is incorrect.', ['attribute' => Yii::t('app', 'Old Password')]));
  121. return false;
  122. }
  123. if ($this->repassword != $this->password) {
  124. $this->addError('repassword', Yii::t('app', '{attribute} is incorrect.', ['attribute' => Yii::t('app', 'Repeat Password')]));
  125. return false;
  126. }
  127. }
  128. }
  129. if (isset($this->password) && $this->password != '') {
  130. $this->setPassword($this->password);
  131. }
  132. }
  133. return parent::beforeSave($insert);
  134. }
  135. /**
  136. * @inheritdoc
  137. */
  138. public function beforeDelete()
  139. {
  140. if ($this->id == 1) {
  141. throw new ForbiddenHttpException(Yii::t('app', "Not allowed to delete {attribute}", ['attribute' => Yii::t('app', 'default super administrator admin')]));
  142. }
  143. return parent::beforeDelete();
  144. }
  145. public function getRolesName()
  146. {
  147. if( in_array( $this->getId(), Yii::$app->getBehavior('access')->superAdminUserIds ) ){
  148. return [Yii::t('app', 'System')];
  149. }
  150. $role = array_keys( Yii::$app->getAuthManager()->getRolesByUser($this->getId()) );
  151. if( !isset( $role[0] ) ) return [];
  152. return $role;
  153. }
  154. public function getRolesNameString($glue=',')
  155. {
  156. $roles = $this->getRolesName();
  157. $str = '';
  158. foreach ($roles as $role){
  159. $str .= Yii::t('menu', $role) . $glue;
  160. }
  161. return rtrim($str, $glue);
  162. }
  163. public function getAvatarUrl(){
  164. $avatarUrl = Yii::$app->getRequest()->getBaseUrl() . '/static/img/profile_small.jpg';
  165. if ($this->avatar) {
  166. $avatarUrl = Yii::$app->params['site']['url'] . $this->avatar;
  167. }
  168. return $avatarUrl;
  169. }
  170. public static function getStatuses()
  171. {
  172. return [
  173. self::STATUS_ACTIVE => Yii::t('app', 'Normal'),
  174. self::STATUS_DELETED => Yii::t('app', 'Disabled'),
  175. ];
  176. }
  177. /**
  178. * @inheritdoc
  179. */
  180. public static function findIdentity($id)
  181. {
  182. return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
  183. }
  184. /**
  185. * @inheritdoc
  186. */
  187. public static function findIdentityByAccessToken($token, $type = null)
  188. {
  189. throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
  190. }
  191. /**
  192. * Finds user by username
  193. *
  194. * @param string $username
  195. * @return static|null
  196. */
  197. public static function findByUsername($username)
  198. {
  199. return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
  200. }
  201. /**
  202. * Finds user by password reset token
  203. *
  204. * @param string $token password reset token
  205. * @return static|null
  206. */
  207. public static function findByPasswordResetToken($token)
  208. {
  209. if (! static::isPasswordResetTokenValid($token)) {
  210. return null;
  211. }
  212. return static::findOne([
  213. 'password_reset_token' => $token,
  214. 'status' => self::STATUS_ACTIVE,
  215. ]);
  216. }
  217. /**
  218. * Finds out if password reset token is valid
  219. *
  220. * @param string $token password reset token
  221. * @return boolean
  222. */
  223. public static function isPasswordResetTokenValid($token)
  224. {
  225. if (empty($token)) {
  226. return false;
  227. }
  228. $timestamp = (int)substr($token, strrpos($token, '_') + 1);
  229. $expire = Yii::$app->params['user.passwordResetTokenExpire'];
  230. return $timestamp + $expire >= time();
  231. }
  232. /**
  233. * Returns an ID that can uniquely identify a user identity.
  234. * @return string|int an ID that uniquely identifies a user identity.
  235. */
  236. public function getId()
  237. {
  238. return $this->id;
  239. }
  240. /**
  241. * Returns a key that can be used to check the validity of a given identity ID.
  242. *
  243. * The key should be unique for each individual user, and should be persistent
  244. * so that it can be used to check the validity of the user identity.
  245. *
  246. * The space of such keys should be big enough to defeat potential identity attacks.
  247. *
  248. * This is required if [[User::enableAutoLogin]] is enabled. The returned key will be stored on the
  249. * client side as a cookie and will be used to authenticate user even if PHP session has been expired.
  250. *
  251. * Make sure to invalidate earlier issued authKeys when you implement force user logout, password change and
  252. * other scenarios, that require forceful access revocation for old sessions.
  253. *
  254. * @return string a key that is used to check the validity of a given identity ID.
  255. * @see validateAuthKey()
  256. */
  257. public function getAuthKey()
  258. {
  259. return $this->auth_key;
  260. }
  261. /**
  262. * Validates the given auth key.
  263. *
  264. * This is required if [[User::enableAutoLogin]] is enabled.
  265. * @param string $authKey the given auth key
  266. * @return bool whether the given auth key is valid.
  267. * @see getAuthKey()
  268. */
  269. public function validateAuthKey($authKey)
  270. {
  271. return $this->getAuthKey() === $authKey;
  272. }
  273. /**
  274. * Validates password
  275. *
  276. * @param string $password password to validate
  277. * @return boolean if password provided is valid for current user
  278. */
  279. public function validatePassword($password)
  280. {
  281. return Yii::$app->security->validatePassword($password, $this->password_hash);
  282. }
  283. /**
  284. * Generates password hash from password and sets it to the model
  285. *
  286. * @param string $password
  287. * @throws \yii\base\Exception
  288. */
  289. public function setPassword($password)
  290. {
  291. $this->password_hash = Yii::$app->security->generatePasswordHash($password);
  292. }
  293. /**
  294. * Generates "remember me" authentication key
  295. */
  296. public function generateAuthKey()
  297. {
  298. $this->auth_key = Yii::$app->security->generateRandomString();
  299. }
  300. /**
  301. * Generates new password reset token
  302. */
  303. public function generatePasswordResetToken()
  304. {
  305. $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
  306. }
  307. /**
  308. * Removes password reset token
  309. */
  310. public function removePasswordResetToken()
  311. {
  312. $this->password_reset_token = null;
  313. }
  314. }