Completed
Push — master ( c80ebb...3b1c77 )
by Antonio
01:53
created

User::afterSave()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
c 1
b 0
f 0
cc 3
eloc 5
nc 2
nop 2
crap 3
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-usuario project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\User\Model;
13
14
use Da\User\Helper\SecurityHelper;
15
use Da\User\Query\UserQuery;
16
use Da\User\Traits\ContainerAwareTrait;
17
use Da\User\Traits\ModuleAwareTrait;
18
use Yii;
19
use yii\base\NotSupportedException;
20
use yii\behaviors\TimestampBehavior;
21
use yii\db\ActiveRecord;
22
use yii\helpers\ArrayHelper;
23
use yii\web\Application;
24
use yii\web\IdentityInterface;
25
26
/**
27
 * User ActiveRecord model.
28
 *
29
 * @property bool $isAdmin
30
 * @property bool $isBlocked
31
 * @property bool $isConfirmed whether user account has been confirmed or not
32
 *
33
 * Database fields:
34
 * @property int $id
35
 * @property string $username
36
 * @property string $email
37
 * @property string $unconfirmed_email
38
 * @property string $password_hash
39
 * @property string $auth_key
40
 * @property int $registration_ip
41
 * @property int $confirmed_at
42
 * @property int $blocked_at
43
 * @property int $flags
44
 * @property int $created_at
45
 * @property int $updated_at
46
 *
47
 * Defined relations:
48
 * @property SocialNetworkAccount[] $socialNetworkAccounts
49
 * @property Profile $profile
50
 */
51
class User extends ActiveRecord implements IdentityInterface
52
{
53
    use ModuleAwareTrait;
54
    use ContainerAwareTrait;
55
56
    // following constants are used on secured email changing process
57
    const OLD_EMAIL_CONFIRMED = 0b1;
58
    const NEW_EMAIL_CONFIRMED = 0b10;
59
60
    /**
61
     * @var string Plain password. Used for model validation
62
     */
63
    public $password;
64
    /**
65
     * @var array connected account list
66
     */
67
    protected $connectedAccounts;
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 6
    public function beforeSave($insert)
73
    {
74
        /** @var SecurityHelper $security */
75 6
        $security = $this->make(SecurityHelper::class);
76 6
        if ($insert) {
77 4
            $this->setAttribute('auth_key', $security->generateRandomString());
78 4
            if (Yii::$app instanceof Application) {
79 4
                $this->setAttribute('registration_ip', Yii::$app->request->getUserIP());
80
            }
81
        }
82
83 6
        if (!empty($this->password)) {
84 6
            $this->setAttribute(
85 6
                'password_hash',
86 6
                $security->generatePasswordHash($this->password, $this->getModule()->blowfishCost)
87
            );
88
        }
89
90 6
        return parent::beforeSave($insert);
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96 6
    public function afterSave($insert, $changedAttributes)
97
    {
98 6
        parent::afterSave($insert, $changedAttributes);
99
100 6
        if ($insert && $this->profile === null) {
101 4
            $profile = $this->make(Profile::class);
102 4
            $profile->link('user', $this);
103
        }
104 6
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109 10
    public static function tableName()
110
    {
111 10
        return '{{%user}}';
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 10
    public function behaviors()
118
    {
119
        return [
120 10
            TimestampBehavior::className(),
121
        ];
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 2
    public function attributeLabels()
128
    {
129
        return [
130 2
            'username' => Yii::t('usuario', 'Username'),
131 2
            'email' => Yii::t('usuario', 'Email'),
132 2
            'registration_ip' => Yii::t('usuario', 'Registration IP'),
133 2
            'unconfirmed_email' => Yii::t('usuario', 'New email'),
134 2
            'password' => Yii::t('usuario', 'Password'),
135 2
            'created_at' => Yii::t('usuario', 'Registration time'),
136 2
            'confirmed_at' => Yii::t('usuario', 'Confirmation time'),
137
        ];
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 6
    public function scenarios()
144
    {
145 6
        return ArrayHelper::merge(
146 6
            parent::scenarios(),
147
            [
148 6
                'register' => ['username', 'email', 'password'],
149
                'connect' => ['username', 'email'],
150
                'create' => ['username', 'email', 'password'],
151
                'update' => ['username', 'email', 'password'],
152
                'settings' => ['username', 'email', 'password'],
153
            ]
154
        );
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 6
    public function rules()
161
    {
162
        return [
163
            // username rules
164 6
            'usernameRequired' => ['username', 'required', 'on' => ['register', 'create', 'connect', 'update']],
165
            'usernameMatch' => ['username', 'match', 'pattern' => '/^[-a-zA-Z0-9_\.@]+$/'],
166
            'usernameLength' => ['username', 'string', 'min' => 3, 'max' => 255],
167
            'usernameTrim' => ['username', 'trim'],
168
            'usernameUnique' => [
169 6
                'username',
170 6
                'unique',
171 6
                'message' => Yii::t('usuario', 'This username has already been taken'),
172
            ],
173
174
            // email rules
175
            'emailRequired' => ['email', 'required', 'on' => ['register', 'connect', 'create', 'update']],
176
            'emailPattern' => ['email', 'email'],
177
            'emailLength' => ['email', 'string', 'max' => 255],
178
            'emailUnique' => [
179 6
                'email',
180 6
                'unique',
181 6
                'message' => Yii::t('usuario', 'This email address has already been taken'),
182
            ],
183
            'emailTrim' => ['email', 'trim'],
184
185
            // password rules
186
            'passwordRequired' => ['password', 'required', 'on' => ['register']],
187
            'passwordLength' => ['password', 'string', 'min' => 6, 'max' => 72, 'on' => ['register', 'create']],
188
        ];
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194
    public function validateAuthKey($authKey)
195
    {
196
        return $this->getAttribute('auth_key') === $authKey;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202 6
    public function getId()
203
    {
204 6
        return $this->getAttribute('id');
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210 1
    public function getAuthKey()
211
    {
212 1
        return $this->getAttribute('auth_key');
213
    }
214
215
    /**
216
     * {@inheritdoc}
217
     */
218 5
    public static function findIdentity($id)
219
    {
220 5
        return static::findOne($id);
221
    }
222
223
    /**
224
     * @return bool whether is blocked or not
225
     */
226 5
    public function getIsBlocked()
227
    {
228 5
        return $this->blocked_at !== null;
229
    }
230
231
    /**
232
     * @return bool whether the user is an admin or not
233
     */
234 2
    public function getIsAdmin()
235
    {
236 2
        return $this->getAuth()->isAdmin($this->username);
237
    }
238
239
    /**
240
     * Returns whether user account has been confirmed or not.
241
     * @return bool whether user account has been confirmed or not
242
     */
243 7
    public function getIsConfirmed()
244
    {
245 7
        return $this->confirmed_at !== null;
246
    }
247
248
    /**
249
     * Checks whether a user has a specific role.
250
     *
251
     * @param string $role
252
     *
253
     * @return bool
254
     */
255
    public function hasRole($role)
256
    {
257
        return $this->getAuth()->hasRole($this->id, $role);
258
    }
259
260
    /**
261
     * @return \yii\db\ActiveQuery
262
     */
263 5
    public function getProfile()
264
    {
265 5
        return $this->hasOne($this->getClassMap()->get(Profile::class), ['user_id' => 'id']);
266
    }
267
268
    /**
269
     * @return SocialNetworkAccount[] social connected accounts [ 'providerName' => socialAccountModel ]
270
     */
271
    public function getSocialNetworkAccounts()
272
    {
273
        if ($this->connectedAccounts == null) {
274
            /** @var SocialNetworkAccount[] $accounts */
275
            $accounts = $this->hasMany(
276
                $this->getClassMap()
277
                    ->get(SocialNetworkAccount::class),
278
                ['user_id' => 'id']
279
            )
280
                ->all();
281
282
            foreach ($accounts as $account) {
283
                $this->connectedAccounts[$account->provider] = $account;
284
            }
285
        }
286
287
        return $this->connectedAccounts;
288
    }
289
290
    /**
291
     * @return UserQuery
292
     */
293 10
    public static function find()
294
    {
295 10
        return new UserQuery(static::class);
296
    }
297
298
    /**
299
     * {@inheritdoc}
300
     */
301
    public static function findIdentityByAccessToken($token, $type = null)
302
    {
303
        throw new NotSupportedException('Method "' . __CLASS__ . '::' . __METHOD__ . '" is not implemented.');
304
    }
305
}
306