BaseUser::generateUniqueRandomString()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 10
c 1
b 0
f 1
dl 0
loc 15
rs 9.6111
cc 5
nc 4
nop 2
1
<?php
2
3
namespace modules\users\models;
4
5
use Yii;
6
use yii\base\Exception;
7
use yii\db\ActiveRecord;
8
use yii\helpers\ArrayHelper;
9
use yii\helpers\Html;
10
use yii\web\IdentityInterface;
11
use modules\users\Module;
12
13
/**
14
 * Class BaseUser
15
 * @package modules\users\models
16
 *
17
 * @property int|string $id ID
18
 * @property string $auth_key Authorization Key
19
 * @property string $email_confirm_token Email Confirm Token
20
 * @property int|string $status
21
 * @property string $statusLabelName
22
 * @property string $statusName
23
 * @property array $statusesArray
24
 * @property-read string $authKey
25
 * @property array $labelsArray
26
 */
27
class BaseUser extends ActiveRecord implements IdentityInterface
28
{
29
    // Statuses
30
    const STATUS_BLOCKED = 0;
31
    const STATUS_ACTIVE = 1;
32
    const STATUS_WAIT = 2;
33
    const STATUS_DELETED = 3;
34
35
    private static $identity;
36
    private static $identityByAccessToken;
37
38
    /**
39
     * {@inheritdoc}
40
     * @return string
41
     */
42
    public static function tableName()
43
    {
44
        return '{{%user}}';
45
    }
46
47
    /**
48
     * @param int|string $id
49
     * @return $this|null
50
     */
51
    public static function findIdentity($id)
52
    {
53
        if (self::$identity === null) {
54
            self::$identity = static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
55
        }
56
        return self::$identity;
57
    }
58
59
    /**
60
     * @param mixed $token
61
     * @param mixed $type
62
     * @return $this|null
63
     */
64
    public static function findIdentityByAccessToken($token, $type = null)
65
    {
66
        if (self::$identityByAccessToken === null) {
67
            self::$identityByAccessToken = static::findOne(['auth_key' => $token, 'status' => self::STATUS_ACTIVE]);
68
        }
69
        return self::$identityByAccessToken;
70
    }
71
72
    /**
73
     * @return int|string
74
     */
75
    public function getId()
76
    {
77
        return $this->id;
78
    }
79
80
    /**
81
     * @return string
82
     */
83
    public function getAuthKey()
84
    {
85
        return $this->auth_key;
86
    }
87
88
    /**
89
     * @param string $authKey
90
     * @return bool
91
     */
92
    public function validateAuthKey($authKey)
93
    {
94
        return $this->getAuthKey() === $authKey;
95
    }
96
97
    /**
98
     * Generates "remember me" authentication key
99
     * @throws Exception
100
     */
101
    public function generateAuthKey()
102
    {
103
        $this->auth_key = $this->generateUniqueRandomString('auth_key');
104
    }
105
106
    /**
107
     * Generates email confirmation token
108
     * @throws Exception
109
     */
110
    public function generateEmailConfirmToken()
111
    {
112
        $this->email_confirm_token = $this->generateUniqueRandomString('email_confirm_token');
113
    }
114
115
    /**
116
     * Generate Unique Random String
117
     * @param string $attribute
118
     * @param int $maxIteration
119
     * @return string
120
     * @throws Exception
121
     */
122
    public function generateUniqueRandomString($attribute, $maxIteration = 10)
123
    {
124
        $security = Yii::$app->security;
125
        if ($attribute && $maxIteration > 0) {
126
            $i = 0;
127
            while ($i <= $maxIteration) {
128
                $string = $security->generateRandomString();
129
                if ((static::findOne([$attribute => $string])) === null) {
130
                    return $string;
131
                }
132
                $i++;
133
            }
134
            throw new Exception('Failed to generate unique value, try increasing the number of iterations.');
135
        }
136
        return $security->generateRandomString();
137
    }
138
139
    /**
140
     * Finds out if password reset token is valid
141
     *
142
     * @param mixed $token password reset token
143
     * @return boolean
144
     */
145
    public static function isPasswordResetTokenValid($token)
146
    {
147
        if (empty($token)) {
148
            return false;
149
        }
150
        $expire = Module::$passwordResetTokenExpire;
151
        $parts = explode('_', $token);
152
        $timestamp = (int)end($parts);
153
        return $timestamp + $expire >= time();
154
    }
155
156
    /**
157
     * Finds user by password reset token
158
     *
159
     * @param mixed $token password reset token
160
     * @return static|null
161
     */
162
    public static function findByPasswordResetToken($token)
163
    {
164
        if (!static::isPasswordResetTokenValid($token)) {
165
            return null;
166
        }
167
        return static::findOne([
168
            'password_reset_token' => $token,
169
            'status' => self::STATUS_ACTIVE
170
        ]);
171
    }
172
173
    /**
174
     * @return array
175
     */
176
    public static function getStatusesArray()
177
    {
178
        return [
179
            self::STATUS_BLOCKED => Module::translate('module', 'Blocked'),
180
            self::STATUS_ACTIVE => Module::translate('module', 'Active'),
181
            self::STATUS_WAIT => Module::translate('module', 'Wait'),
182
            self::STATUS_DELETED => Module::translate('module', 'Deleted')
183
        ];
184
    }
185
186
    /**
187
     * @return array
188
     */
189
    public static function getLabelsArray()
190
    {
191
        return [
192
            self::STATUS_BLOCKED => 'default',
193
            self::STATUS_ACTIVE => 'success',
194
            self::STATUS_WAIT => 'warning',
195
            self::STATUS_DELETED => 'danger'
196
        ];
197
    }
198
199
    /**
200
     * @return mixed|null
201
     * @throws \Exception
202
     */
203
    public function getStatusName()
204
    {
205
        return ArrayHelper::getValue(self::getStatusesArray(), $this->status);
206
    }
207
208
    /**
209
     * Return <span class="label label-success">Active</span>
210
     *
211
     * @return string
212
     * @throws \Exception
213
     */
214
    public function getStatusLabelName()
215
    {
216
        $name = ArrayHelper::getValue(self::getLabelsArray(), $this->status);
217
        return Html::tag('span', $this->getStatusName(), ['class' => 'label label-' . $name]);
218
    }
219
}
220