Issues (1256)

models/User.php (7 issues)

1
<?php
2
3
namespace app\models;
4
5
use Yii;
6
use yii\helpers\ArrayHelper;
7
use yii\web\IdentityInterface;
8
use yii\rbac\Role as BaseRole;
9
use Itstructure\AdminModule\interfaces\AdminMenuInterface;
10
use Itstructure\RbacModule\interfaces\RbacIdentityInterface;
11
use Itstructure\MFUploader\behaviors\BehaviorMediafile;
12
use Itstructure\MFUploader\models\Mediafile;
13
use Itstructure\MFUploader\interfaces\UploadModelInterface;
14
use app\traits\ThumbnailTrait;
15
16
/**
17
 * Class User model.
18
 *
19
 * @property int $id
20
 * @property int $order
21
 * @property int $public
22
 * @property int $minOrder
23
 * @property int $maxOrder
24
 * @property string $first_name
25
 * @property string $last_name
26
 * @property string $patronymic
27
 * @property string $login
28
 * @property string $email
29
 * @property string $phone
30
 * @property string  $passwordRepeat Password confirmed.
31
 * @property int|string  $thumbnail Thumbnail(mediafile id or url).
32
 * @property array|null|\yii\db\ActiveRecord|Mediafile $thumbnailModel
33
 * @property Position $position
34
 *
35
 * @package app\models
36
 */
37
class User extends ActiveRecord implements RbacIdentityInterface, AdminMenuInterface
38
{
39
    use ThumbnailTrait;
0 ignored issues
show
The trait app\traits\ThumbnailTrait requires the property $alt which is not provided by app\models\User.
Loading history...
40
41
    /**
42
     * Password confirmed.
43
     *
44
     * @var string
45
     */
46
    public $passwordRepeat;
47
48
    /**
49
     * Thumbnail(mediafile id or url).
50
     *
51
     * @var int|string
52
     */
53
    public $thumbnail;
54
55
    /**
56
     * @inheritdoc
57
     */
58
    public static function tableName()
59
    {
60
        return 'users';
61
    }
62
63
    /**
64
     * @inheritdoc
65
     */
66
    public function rules()
67
    {
68
        return [
69
            [
70
                [
71
                    'created_at',
72
                    'updated_at',
73
                ],
74
                'safe',
75
            ],
76
            [
77
                [
78
                    'first_name',
79
                    'login',
80
                    'email',
81
                ],
82
                'required',
83
            ],
84
            [
85
                [
86
                    'status',
87
                    'public',
88
                    'order',
89
                    'position_id',
90
                ],
91
                'integer',
92
            ],
93
            [
94
                [
95
                    'first_name',
96
                    'last_name',
97
                    'patronymic',
98
                    'login',
99
                    'email',
100
                    'phone',
101
                    'hashedPassword',
102
                ],
103
                'string',
104
                'max' => 255,
105
            ],
106
            [
107
                [
108
                    'about',
109
                ],
110
                'string',
111
            ],
112
            [
113
                'login',
114
                'unique',
115
            ],
116
            [
117
                'email',
118
                'unique',
119
            ],
120
            [
121
                'email',
122
                'email',
123
            ],
124
            [
125
                UploadModelInterface::FILE_TYPE_THUMB,
126
                function($attribute) {
127
                    if (!is_numeric($this->{$attribute}) && !is_string($this->{$attribute})) {
128
                        $this->addError($attribute, 'Tumbnail content must be a numeric or string.');
129
                    }
130
                },
131
                'skipOnError' => false,
132
            ],
133
            [
134
                [
135
                    'position_id'
136
                ],
137
                'exist',
138
                'skipOnError' => true,
139
                'targetClass' => Position::class,
140
                'targetAttribute' => ['position_id' => 'id']
141
            ],
142
        ];
143
    }
144
145
    /**
146
     * @inheritdoc
147
     */
148
    public function behaviors()
149
    {
150
        return ArrayHelper::merge(parent::behaviors(), [
151
            'mediafile' => [
152
                'class' => BehaviorMediafile::class,
153
                'name' => static::tableName(),
154
                'attributes' => [
155
                    UploadModelInterface::FILE_TYPE_THUMB,
156
                ],
157
            ],
158
        ]);
159
    }
160
161
    /**
162
     * @return array
163
     */
164
    public function attributes()
165
    {
166
        return ArrayHelper::merge(parent::attributes(), [
167
            UploadModelInterface::FILE_TYPE_THUMB,
168
        ]);
169
    }
170
171
    /**
172
     * @inheritdoc
173
     */
174
    public function attributeLabels()
175
    {
176
        return [
177
            'id' => 'ID',
178
            'first_name' => Yii::t('users', 'First Name'),
179
            'login' => Yii::t('users', 'Login'),
180
            'email' => Yii::t('users', 'Email'),
181
            'password' => Yii::t('users', 'Password'),
182
            'passwordRepeat' => Yii::t('users', 'Password confirm'),
183
            'created_at' => Yii::t('app', 'Created date'),
184
            'updated_at' => Yii::t('app', 'Updated date'),
185
            UploadModelInterface::FILE_TYPE_THUMB => Yii::t('users', 'Avatar'),
186
        ];
187
    }
188
189
    /**
190
     * @return \yii\db\ActiveQuery|Position
191
     */
192
    public function getPosition()
193
    {
194
        return $this->hasOne(Position::class, [
195
            'id' => 'position_id'
196
        ]);
197
    }
198
199
    /**
200
     * @return array|\yii\db\ActiveRecord[]
201
     */
202
    public static function getPublicUsers()
203
    {
204
        return static::find()
205
            ->where([
206
                'public' => 1
207
            ])->orderBy([
208
                'order' => SORT_ASC
209
            ])->all();
210
    }
211
212
    /**
213
     * Find user by login.
214
     *
215
     * @param string $login
216
     *
217
     * @return User|null
218
     */
219
    public static function findByLogin($login)
220
    {
221
        return static::findOne([
222
            'login' => $login,
223
        ]);
224
    }
225
226
    /**
227
     * Finds an identity by the given ID.
228
     *
229
     * @param string|int $id the ID to be looked for
230
     *
231
     * @return IdentityInterface the identity object that matches the given ID.
232
     * Null should be returned if such an identity cannot be found
233
     * or the identity is not in an active state (disabled, deleted, etc.)
234
     */
235
    public static function findIdentity($id)
236
    {
237
        return static::findOne($id);
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::findOne($id) returns the type yii\db\ActiveRecord which is incompatible with the documented return type yii\web\IdentityInterface.
Loading history...
238
    }
239
240
    /**
241
     * Finds an identity by the given token.
242
     *
243
     * @param mixed $token the token to be looked for
244
     *
245
     * @param mixed $type  the type of the token. The value of this parameter depends on the
246
     *                     implementation. For example, [[\yii\filters\auth\HttpBearerAuth]] will
247
     *                     set this parameter to be `yii\filters\auth\HttpBearerAuth`.
248
     *
249
     * @return IdentityInterface the identity object that matches the given token.
250
     * Null should be returned if such an identity cannot be found
251
     * or the identity is not in an active state (disabled, deleted, etc.)
252
     */
253
    public static function findIdentityByAccessToken($token, $type = null)
254
    {
255
        return null;
256
    }
257
258
    /**
259
     * Returns an ID that can uniquely identify a user identity.
260
     *
261
     * @return string|int an ID that uniquely identifies a user identity.
262
     */
263
    public function getId()
264
    {
265
        return $this->id;
266
    }
267
268
    /**
269
     * Returns a key that can be used to check the validity of a given identity ID.
270
     *
271
     * The key should be unique for each individual user, and should be persistent
272
     * so that it can be used to check the validity of the user identity.
273
     *
274
     * The space of such keys should be big enough to defeat potential identity attacks.
275
     *
276
     * This is required if [[User::enableAutoLogin]] is enabled.
277
     *
278
     * @return string a key that is used to check the validity of a given identity ID.
279
     *
280
     * @see validateAuthKey()
281
     */
282
    public function getAuthKey()
283
    {
284
        return '';
285
    }
286
287
    /**
288
     * Validates the given auth key.
289
     *
290
     * This is required if [[User::enableAutoLogin]] is enabled.
291
     *
292
     * @param string $authKey the given auth key
293
     *
294
     * @return bool whether the given auth key is valid.
295
     *
296
     * @see getAuthKey()
297
     */
298
    public function validateAuthKey($authKey)
299
    {
300
        return true;
301
    }
302
303
    /**
304
     * Return user's full name.
305
     *
306
     * @return string
307
     */
308
    public function getFullName(): string
309
    {
310
        return $this->first_name . ' ' . $this->last_name;
311
    }
312
313
    /**
314
     * Return user's name.
315
     *
316
     * @return string
317
     */
318
    public function getUserName(): string
319
    {
320
        return $this->first_name;
321
    }
322
323
    /**
324
     * Return role name of user, e.g. "Admin" or "Web Developer"
325
     *
326
     * @return string
327
     */
328
    public function getRoleName(): string
329
    {
330
        return implode(', ', array_keys($this->getRoles()));
331
    }
332
333
    /**
334
     * List of profile assigned roles.
335
     *
336
     * @return BaseRole[]
337
     */
338
    public function getRoles()
339
    {
340
        return Yii::$app->authManager->getRolesByUser($this->getId());
341
    }
342
343
    /**
344
     * Return the date when user was registered (sign-up).
345
     *
346
     * @return \DateTime
347
     */
348
    public function getRegisterDate()
349
    {
350
        return new \DateTime($this->created_at);
0 ignored issues
show
Bug Best Practice introduced by
The property created_at does not exist on app\models\User. Since you implemented __get, consider adding a @property annotation.
Loading history...
351
    }
352
353
    /**
354
     * Does the user have an avatar.
355
     *
356
     * @return boolean
357
     */
358
    public function hasAvatar(): bool
359
    {
360
        return $this->getThumbnailModel() !== null;
361
    }
362
363
    /**
364
     * Return a link to avatar image.
365
     *
366
     * @return string
367
     */
368
    public function getAvatar(): string
369
    {
370
        $defaultThumbUrl = $this->getDefaultThumbUrl();
371
372
        return empty($defaultThumbUrl) ? '' : $defaultThumbUrl;
373
    }
374
375
    /**
376
     * Set hashed password.
377
     *
378
     * @param string $password.
379
     *
380
     * @return $this
381
     */
382
    public function setPassword($password)
383
    {
384
        if (!empty($password)) {
385
            $this->hashedPassword = $this->generateHash($password);
0 ignored issues
show
Bug Best Practice introduced by
The property hashedPassword does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
386
        }
387
388
        return $this;
389
    }
390
391
    /**
392
     * Validate password.
393
     *
394
     * @param string $password.
395
     *
396
     * @return bool.
0 ignored issues
show
Documentation Bug introduced by
The doc comment bool. at position 0 could not be parsed: Unknown type name 'bool.' at position 0 in bool..
Loading history...
397
     */
398
    public function validatePassword($password)
399
    {
400
        return Yii::$app->getSecurity()
401
            ->validatePassword($password, $this->hashedPassword);
402
    }
403
404
    /**
405
     * @return int
406
     */
407
    public function getMinOrder(): int
408
    {
409
        $result = static::find()
410
            ->select('order')
411
            ->orderBy('order ASC')
412
            ->one();
413
414
        return $result == null ? 1 : $result->order;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result == null ? 1 : $result->order could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
415
    }
416
417
    /**
418
     * @return int
419
     */
420
    public function getMaxOrder(): int
421
    {
422
        $result = static::find()
423
            ->select('order')
424
            ->orderBy('order DESC')
425
            ->one();
426
427
        return $result == null ? 1 : $result->order;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result == null ? 1 : $result->order could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
428
    }
429
430
    /**
431
     * @param int $order
432
     */
433
    public function moveOrder(int $order): void
434
    {
435
        if ($order == $this->order){
436
            return;
437
        }
438
439
        /* @var static $future */
440
        $future = static::find()
441
            ->where([
442
                'order' => $order
443
            ])
444
            ->one();
445
        $future->detachBehavior('mediafile');
446
        $future->order = $order > $this->order ? $order-1 : $order+1;
447
        $future->save();
448
449
        $this->detachBehavior('mediafile');
450
        $this->order = $order;
451
        $this->save();
452
    }
453
454
    /**
455
     * @param bool $insert
456
     *
457
     * @return bool
458
     */
459
    public function beforeSave($insert)
460
    {
461
        if ($this->isNewRecord){
462
            $this->order = $this->maxOrder == null ? 1 : $this->maxOrder + 1;
463
        }
464
465
        return parent::beforeSave($insert);
466
    }
467
468
    /**
469
     * Generate hash by password.
470
     *
471
     * @param string $password.
472
     *
473
     * @return string
474
     */
475
    private function generateHash($password)
476
    {
477
        return Yii::$app->getSecurity()
478
            ->generatePasswordHash($password);
479
    }
480
}
481