Completed
Push — master ( 18edfa...a3fde4 )
by Alexey
03:57
created

User::getId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace modules\users\models;
4
5
use Yii;
6
use yii\base\Exception;
7
use yii\db\ActiveQuery;
8
use yii\db\StaleObjectException;
9
use yii\helpers\Html;
10
use yii\db\ActiveRecord;
11
use yii\behaviors\TimestampBehavior;
12
use yii2tech\ar\softdelete\SoftDeleteBehavior;
13
use modules\rbac\models\Role;
14
use modules\users\models\query\UserQuery;
15
use modules\users\traits\ModuleTrait;
16
use modules\users\Module;
17
18
/**
19
 * This is the model class for table "{{%user}}".
20
 *
21
 * @property int $id ID
22
 * @property string $username Username
23
 * @property string $email Email
24
 * @property string $auth_key Authorization Key
25
 * @property string $password_hash Hash Password
26
 * @property string $password_reset_token Password Token
27
 * @property string $email_confirm_token Email Confirm Token
28
 * @property int $created_at Created
29
 * @property int $updated_at Updated
30
 * @property int $status Status
31
 *
32
 * @property UserProfile $profile
33
 * @property string $statusLabelName
34
 * @property string $statusName
35
 * @property array $statusesArray
36
 * @property string $labelMailConfirm
37
 * @property string $newPassword
38
 *
39
 * @method touch() TimestampBehavior
40
 */
41
class User extends BaseUser
42
{
43
    use ModuleTrait;
44
45
    // Length password
46
    const LENGTH_STRING_PASSWORD_MIN = 2;
47
    const LENGTH_STRING_PASSWORD_MAX = 32;
48
49
    const SCENARIO_ADMIN_CREATE = 'adminCreate';
50
51
    /**
52
     * @var string
53
     */
54
    public $password;
55
56
    /**
57
     * {@inheritdoc}
58
     * @return array
59
     */
60
    public function behaviors()
61
    {
62
        return [
63
            'timestamp' => [
64
                'class' => TimestampBehavior::class
65
            ],
66
            'softDeleteBehavior' => [
67
                'class' => SoftDeleteBehavior::class,
68
                'softDeleteAttributeValues' => [
69
                    'status' => self::STATUS_DELETED
70
                ]
71
            ]
72
        ];
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     * @return array
78
     */
79
    public function rules()
80
    {
81
        return [
82
            ['username', 'required'],
83
            ['username', 'match', 'pattern' => '#^[\w_-]+$#i'],
84
            ['username', 'unique', 'targetClass' => self::class, 'message' => Module::t('module', 'This username is already taken.')],
85
            ['username', 'string', 'min' => 2, 'max' => 255],
86
87
            ['email', 'required'],
88
            ['email', 'email'],
89
            ['email', 'unique', 'targetClass' => self::class, 'message' => Module::t('module', 'This email is already taken.')],
90
            ['email', 'string', 'max' => 255],
91
            [['auth_key'], 'string', 'max' => 32],
92
            [['password_reset_token'], 'unique'],
93
94
            ['status', 'integer'],
95
            ['status', 'default', 'value' => self::STATUS_WAIT],
96
            ['status', 'in', 'range' => array_keys(self::getStatusesArray())],
97
98
            [['password'], 'required', 'on' => self::SCENARIO_ADMIN_CREATE],
99
            [['password'], 'string', 'min' => self::LENGTH_STRING_PASSWORD_MIN, 'max' => self::LENGTH_STRING_PASSWORD_MAX]
100
        ];
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     * @return array
106
     */
107
    public function attributeLabels()
108
    {
109
        return [
110
            'id' => Module::t('module', 'ID'),
111
            'username' => Module::t('module', 'Username'),
112
            'email' => Module::t('module', 'Email'),
113
            'auth_key' => Module::t('module', 'Auth Key'),
114
            'password_hash' => Module::t('module', 'Hash Password'),
115
            'password_reset_token' => Module::t('module', 'Password Token'),
116
            'email_confirm_token' => Module::t('module', 'Email Confirm Token'),
117
            'created_at' => Module::t('module', 'Created'),
118
            'updated_at' => Module::t('module', 'Updated'),
119
            'status' => Module::t('module', 'Status'),
120
            'userRoleName' => Module::t('module', 'User Role Name'),
121
            'password' => Module::t('module', 'Password')
122
        ];
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     * @return UserQuery the active query used by this AR class.
128
     */
129
    public static function find()
130
    {
131
        return new UserQuery(static::class);
132
    }
133
134
    /**
135
     * @return ActiveQuery
136
     */
137
    public function getProfile()
138
    {
139
        return $this->hasOne(UserProfile::class, ['user_id' => 'id']);
140
    }
141
142
    /**
143
     * Generates password hash from password and sets it to the model
144
     *
145
     * @param string $password
146
     * @throws Exception
147
     */
148
    public function setPassword($password)
149
    {
150
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
151
    }
152
153
    /**
154
     * Removes password reset token
155
     */
156
    public function removePasswordResetToken()
157
    {
158
        $this->password_reset_token = null;
159
    }
160
161
    /**
162
     * Generates new password reset token
163
     * @throws Exception
164
     */
165
    public function generatePasswordResetToken()
166
    {
167
        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
168
    }
169
170
    /**
171
     * Validates password
172
     *
173
     * @param string $password password to validate
174
     * @return bool if password provided is valid for current user
175
     */
176
    public function validatePassword($password)
177
    {
178
        return Yii::$app->security->validatePassword($password, $this->password_hash);
179
    }
180
181
    /**
182
     * Finds user by email
183
     *
184
     * @param string $email
185
     * @return array|null|ActiveRecord
186
     */
187
    public static function findByUsernameEmail($email)
188
    {
189
        return static::findOne(['email' => $email, 'status' => self::STATUS_ACTIVE]);
190
    }
191
192
    /**
193
     * Finds user by username or email
194
     *
195
     * @param string $string
196
     * @return array|null|ActiveRecord
197
     */
198
    public static function findByUsernameOrEmail($string)
199
    {
200
        return static::find()
201
            ->where(['or', ['username' => $string], ['email' => $string]])
202
            ->andWhere(['status' => self::STATUS_ACTIVE])
203
            ->one();
204
    }
205
206
    /**
207
     * @param mixed $email_confirm_token
208
     * @return bool|null|static
209
     */
210
    public static function findByEmailConfirmToken($email_confirm_token)
211
    {
212
        return static::findOne([
213
            'email_confirm_token' => $email_confirm_token,
214
            'status' => self::STATUS_WAIT
215
        ]);
216
    }
217
218
    /**
219
     * Removes email confirmation token
220
     */
221
    public function removeEmailConfirmToken()
222
    {
223
        $this->email_confirm_token = null;
224
    }
225
226
    /**
227
     * @param string $name
228
     * @return string
229
     */
230
    public function getLabelMailConfirm($name = 'default')
231
    {
232
        if ($this->status === self::STATUS_WAIT) {
233
            return Html::tag('span', Html::tag('span', '', [
234
                'class' => 'glyphicon glyphicon-envelope'
235
            ]), ['class' => 'label label-' . $name]);
236
        }
237
        return '';
238
    }
239
240
    /**
241
     * @return bool
242
     */
243
    public function sendConfirmEmail()
244
    {
245
        return Yii::$app->mailer->compose([
246
            'html' => '@modules/users/mail/emailConfirm-html',
247
            'text' => '@modules/users/mail/emailConfirm-text'
248
        ], ['user' => $this])
249
            ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name])
250
            ->setTo($this->email)
251
            ->setSubject(Module::t('module', 'Account activation!') . ' ' . Yii::$app->name)
252
            ->send();
253
    }
254
255
    /**
256
     * Set Status
257
     * @return int|string
258
     */
259
    public function setStatus()
260
    {
261
        switch ($this->status) {
262
            case self::STATUS_ACTIVE:
263
                $this->status = self::STATUS_BLOCKED;
264
                break;
265
            case self::STATUS_DELETED:
266
                $this->status = self::STATUS_WAIT;
267
                break;
268
            default:
269
                $this->status = self::STATUS_ACTIVE;
270
        }
271
        return $this->status;
272
    }
273
274
    /**
275
     * @return string
276
     */
277
    public function getUserFullName()
278
    {
279
        $fullName = Module::t('module', 'Guest');
280
        if (!Yii::$app->user->isGuest) {
281
            $fullName = $this->profile->first_name . ' ' . $this->profile->last_name;
282
            $fullName = ($fullName !== ' ') ? $fullName : $this->username;
283
        }
284
        return Html::encode(trim($fullName));
285
    }
286
287
    /**
288
     * @param integer|string $id
289
     * @return bool
290
     */
291
    public function isSuperAdmin($id = '')
292
    {
293
        $id = $id ?: $this->id;
294
        $authManager = Yii::$app->authManager;
295
        $roles = $authManager->getRolesByUser($id);
296
        foreach ($roles as $role) {
297
            if ($role->name === Role::ROLE_SUPER_ADMIN) {
298
                return true;
299
            }
300
        }
301
        return false;
302
    }
303
304
    /**
305
     * @return bool
306
     */
307
    public function isDeleted()
308
    {
309
        return $this->status === self::STATUS_DELETED;
310
    }
311
312
    /**
313
     * @param bool $insert
314
     * @return bool
315
     * @throws Exception
316
     */
317
    public function beforeSave($insert)
318
    {
319
        if (parent::beforeSave($insert)) {
320
            if ($insert) {
321
                $this->generateAuthKey();
322
            }
323
            if (!empty($this->newPassword)) {
324
                $this->setPassword($this->newPassword);
325
            }
326
            return true;
327
        }
328
        return false;
329
    }
330
331
    /**
332
     * @param bool $insert
333
     * @param array $changedAttributes
334
     */
335
    public function afterSave($insert, $changedAttributes)
336
    {
337
        parent::afterSave($insert, $changedAttributes);
338
        if ($insert) {
339
            $profile = new UserProfile([
340
                'user_id' => $this->id,
341
                'email_gravatar' => $this->email
342
            ]);
343
            $profile->save();
344
        }
345
    }
346
347
    /**
348
     * @return bool
349
     * @throws \Throwable
350
     * @throws StaleObjectException
351
     */
352
    public function beforeDelete()
353
    {
354
        if ($this->isDeleted()) {
355
            $this->profile->delete();
356
            // Отвязываем от ролей
357
            $authManager = Yii::$app->getAuthManager();
358
            if ($authManager->getRolesByUser($this->id)) {
359
                $authManager->revokeAll($this->id);
360
            }
361
        }
362
        return parent::beforeDelete();
363
    }
364
}
365