These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * _ __ __ _____ _____ ___ ____ _____ |
||
5 | * | | / // // ___//_ _// || __||_ _| |
||
6 | * | |/ // /(__ ) / / / /| || | | | |
||
7 | * |___//_//____/ /_/ /_/ |_||_| |_| |
||
8 | * @link https://vistart.me/ |
||
9 | * @copyright Copyright (c) 2016 - 2017 vistart |
||
10 | * @license https://vistart.me/license/ |
||
11 | */ |
||
12 | |||
13 | namespace rhosocial\user; |
||
14 | |||
15 | use rhosocial\base\models\models\BaseUserModel; |
||
16 | use rhosocial\base\models\queries\BaseBlameableQuery; |
||
17 | use rhosocial\user\models\invitation\registration\UserInvitationRegistrationTrait; |
||
18 | use rhosocial\user\models\log\UserLoginTrait; |
||
19 | use rhosocial\user\models\UserUsernameTrait; |
||
20 | use rhosocial\user\security\UserPasswordHistoryTrait; |
||
21 | use Yii; |
||
22 | use yii\base\Event; |
||
23 | use yii\base\InvalidConfigException; |
||
24 | use yii\behaviors\AttributeBehavior; |
||
25 | use yii\caching\TagDependency; |
||
26 | use yii\db\ActiveRecord; |
||
27 | use yii\widgets\ActiveForm; |
||
28 | |||
29 | /** |
||
30 | * Common User Model. |
||
31 | * This model should be stored in a relational database. You can create a foreign |
||
32 | * key constraint on other models and this model. |
||
33 | * |
||
34 | * If you're using MySQL, we recommend that you create a data table using the following statement: |
||
35 | * |
||
36 | * ``` |
||
37 | * CREATE TABLE `user` ( |
||
38 | * `guid` varbinary(16) NOT NULL COMMENT 'GUID', |
||
39 | * `id` varchar(16) COLLATE utf8_unicode_ci NOT NULL COMMENT 'ID', |
||
40 | * `pass_hash` varchar(80) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Password Hash', |
||
41 | * `ip` varbinary(16) NOT NULL DEFAULT '0' COMMENT 'IP', |
||
42 | * `ip_type` tinyint(3) unsigned NOT NULL DEFAULT '4' COMMENT 'IP Address Type', |
||
43 | * `created_at` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT 'Create Time', |
||
44 | * `updated_at` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT 'Update Time', |
||
45 | * `auth_key` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Authentication Key', |
||
46 | * `access_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Access Token', |
||
47 | * `password_reset_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Password Reset Token', |
||
48 | * `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT 'Status', |
||
49 | * `type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Type', |
||
50 | * `source` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Source', |
||
51 | * PRIMARY KEY (`guid`), |
||
52 | * UNIQUE KEY `user_id_unique` (`id`), |
||
53 | * UNIQUE KEY `user_username_unique` (`username`), |
||
54 | * KEY `user_auth_key_normal` (`auth_key`), |
||
55 | * KEY `user_access_token_normal` (`access_token`), |
||
56 | * KEY `user_password_reset_token` (`password_reset_token`), |
||
57 | * KEY `user_create_time_normal` (`created_at`) |
||
58 | * ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='User'; |
||
59 | * ``` |
||
60 | * |
||
61 | * The fields of User table in database are following: |
||
62 | * @property string $guid User's GUID. This property is used to uniquely identify a user. |
||
63 | * This property is automatically generated when the class is created, we do not |
||
64 | * recommend that you modify this property, unless you know the consequences of doing so. |
||
65 | * This property is also regareded as the foreign key target of other models associated |
||
66 | * with this model. If you have to modify this property, the foreign key constraints |
||
67 | * should be updating and deleting on cascade. |
||
68 | * @property string $id User Identifier No. It is a 8-digit number beginning with 4 by default. |
||
69 | * @property string $pass_hash Password Hash. |
||
70 | * We strongly recommend you NOT to change this property directly! |
||
71 | * If you want to set or reset password, please use setPassword() magic property instead. |
||
72 | * @property integer $ip IP address. |
||
73 | * @property integer $ipType |
||
74 | * @property string $createdAt |
||
75 | * @property string $updatedAt |
||
76 | * @property string $auth_key |
||
77 | * @property string $access_token |
||
78 | * @property string $password_reset_token |
||
79 | * @property integer $status |
||
80 | * @property integer $type |
||
81 | * @property string $source |
||
82 | * |
||
83 | * @property-read Profile $profile Profile. This magic property is read-only. |
||
84 | * If you want to modify anyone property of Profile model, please get it first, |
||
85 | * then change and save it, like following: |
||
86 | * ```php |
||
87 | * $profile = $user->profile; |
||
88 | * $profile->nickname = 'vistart'; |
||
89 | * $profile->save(); |
||
90 | * ``` |
||
91 | * If $profileClass is `false`, `null` returned. |
||
92 | * @version 1.0 |
||
93 | * @author vistart <[email protected]> |
||
94 | */ |
||
95 | class User extends BaseUserModel |
||
96 | { |
||
97 | use UserPasswordHistoryTrait, UserLoginTrait, UserUsernameTrait, UserInvitationRegistrationTrait; |
||
98 | |||
99 | /** |
||
100 | * @var string |
||
101 | */ |
||
102 | public $searchClass = UserSearch::class; |
||
103 | |||
104 | /** |
||
105 | * @return null |
||
106 | */ |
||
107 | public function getSearchModel() |
||
108 | { |
||
109 | $class = $this->searchClass; |
||
110 | if (empty($class) || !class_exists($class)) { |
||
111 | return null; |
||
112 | } |
||
113 | return new $class; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * @inheritdoc |
||
118 | */ |
||
119 | 1 | public function attributeLabels() |
|
120 | { |
||
121 | $labels = [ |
||
122 | 1 | $this->guidAttribute => Yii::t('user', 'GUID'), |
|
123 | 1 | $this->idAttribute => Yii::t('user', 'ID'), |
|
124 | 1 | $this->passwordHashAttribute => Yii::t('user', 'Password Hash'), |
|
125 | 1 | $this->ipAttribute => Yii::t('user', 'IP Address'), |
|
126 | 1 | $this->ipTypeAttribute => Yii::t('user', 'IP Address Type'), |
|
127 | 1 | $this->createdAtAttribute => Yii::t('user', 'Creation Time'), |
|
128 | 1 | $this->updatedAtAttribute => Yii::t('user', 'Last Updated Time'), |
|
129 | 1 | $this->authKeyAttribute => Yii::t('user', 'Authentication Key'), |
|
130 | 1 | $this->accessTokenAttribute => Yii::t('user', 'Access Token'), |
|
131 | 1 | $this->passwordResetTokenAttribute => Yii::t('user', 'Password Reset Token'), |
|
132 | 1 | $this->statusAttribute => Yii::t('user', 'Status'), |
|
133 | 1 | 'type' => Yii::t('user', 'Type'), |
|
134 | 1 | $this->sourceAttribute => Yii::t('user', 'Source'), |
|
135 | 1 | 'createdAt' => Yii::t('user', 'Registration Time'), |
|
136 | 1 | 'updatedAt' => Yii::t('user', 'Last Updated Time'), |
|
137 | ]; |
||
138 | 1 | return $labels; |
|
139 | } |
||
140 | |||
141 | /** |
||
142 | * @inheritdoc |
||
143 | */ |
||
144 | public $idAttributeType = 1; |
||
145 | |||
146 | /** |
||
147 | * @inheritdoc |
||
148 | */ |
||
149 | public $idAttributeLength = 8; |
||
150 | |||
151 | /** |
||
152 | * @inheritdoc |
||
153 | */ |
||
154 | public $idAttributePrefix = '4'; |
||
155 | |||
156 | /** |
||
157 | * @var bool |
||
158 | */ |
||
159 | public $idPreassigned = true; |
||
160 | |||
161 | /** |
||
162 | * @inheritdoc |
||
163 | */ |
||
164 | 53 | public static function tableName() |
|
165 | { |
||
166 | 53 | return '{{%user}}'; |
|
167 | } |
||
168 | |||
169 | /** |
||
170 | * @var string|false Profile class name. If you do not need profile model, |
||
171 | * please set it false. |
||
172 | */ |
||
173 | public $profileClass = false; |
||
174 | |||
175 | /** |
||
176 | * @inheritdoc |
||
177 | * ----------- |
||
178 | * When the user is updated or deleted, the cache contents tagged with the corresponding user tag will be invalidated. |
||
179 | */ |
||
180 | 53 | public function init() |
|
181 | { |
||
182 | 53 | $this->on(static::$eventAfterRegister, [$this, 'onAddPasswordToHistory']); |
|
183 | 53 | $this->on(static::$eventAfterResetPassword, [$this, 'onAddPasswordToHistory']); |
|
184 | 53 | $this->on(static::EVENT_AFTER_UPDATE, [$this, 'onInvalidTags']); |
|
185 | 53 | $this->on(static::EVENT_AFTER_DELETE, [$this, 'onInvalidTags']); |
|
186 | 53 | parent::init(); |
|
187 | 53 | } |
|
188 | |||
189 | /** |
||
190 | * @var string |
||
191 | */ |
||
192 | public $cacheTagPrefix = 'tag_user_'; |
||
193 | |||
194 | /** |
||
195 | * Get cache tag. |
||
196 | * The cache tag ends with the user ID, but after the user ID is modified, the old ID will prevail. |
||
197 | * @return string |
||
198 | */ |
||
199 | 44 | public function getCacheTag() |
|
200 | { |
||
201 | 44 | return $this->cacheTagPrefix . |
|
202 | 44 | ($this->isAttributeChanged($this->idAttribute) ? $this->getOldAttribute($this->idAttribute) : $this->getID()); |
|
203 | } |
||
204 | |||
205 | /** |
||
206 | * @param Event $event |
||
207 | * @return bool|string|array |
||
208 | */ |
||
209 | 44 | public function onInvalidTags($event) |
|
210 | { |
||
211 | try { |
||
212 | 44 | $cache = Yii::$app->get('cache'); |
|
213 | } catch (InvalidConfigException $ex) { |
||
0 ignored issues
–
show
|
|||
214 | return true; |
||
215 | } |
||
216 | 44 | $sender = $event->sender; |
|
217 | /*@var $sender static */ |
||
218 | 44 | return TagDependency::invalidate($cache, $sender->getCacheTag()); |
|
219 | } |
||
220 | |||
221 | /** |
||
222 | * Create profile. |
||
223 | * If profile of this user exists, it will be returned instead of creating it. |
||
224 | * Meanwhile, the $config parameter will be skipped. |
||
225 | * @param array $config Profile configuration. Skipped if it exists. |
||
226 | * @return Profile |
||
227 | */ |
||
228 | 19 | public function createProfile($config = []) |
|
229 | { |
||
230 | 19 | $profileClass = $this->profileClass; |
|
231 | 19 | if (empty($profileClass) || !is_string($this->profileClass)) { |
|
232 | 1 | return null; |
|
233 | } |
||
234 | 18 | $profile = $profileClass::findOne($this->getGUID()); |
|
235 | 18 | if (!$profile) { |
|
236 | 18 | $profile = $this->create($profileClass, $config); |
|
237 | 18 | $profile->setGUID($this->getGUID()); |
|
238 | } |
||
239 | 18 | return $profile; |
|
240 | } |
||
241 | |||
242 | /** |
||
243 | * |
||
244 | * @return boolean |
||
245 | */ |
||
246 | 4 | public function hasProfile() |
|
247 | { |
||
248 | 4 | if ($this->profileClass === false || !is_string($this->profileClass) || !class_exists($this->profileClass)) { |
|
249 | 2 | return false; |
|
250 | } |
||
251 | 2 | return true; |
|
252 | } |
||
253 | |||
254 | /** |
||
255 | * Get Profile query. |
||
256 | * If you want to get profile model, please access this method in magic property way, |
||
257 | * like following: |
||
258 | * |
||
259 | * ```php |
||
260 | * $user->profile; |
||
261 | * ``` |
||
262 | * |
||
263 | * @return BaseBlameableQuery |
||
264 | */ |
||
265 | 4 | public function getProfile() |
|
266 | { |
||
267 | 4 | if (!$this->hasProfile()) { |
|
268 | 2 | return null; |
|
269 | } |
||
270 | 2 | $profileClass = $this->profileClass; |
|
271 | 2 | $profileModel = $profileClass::buildNoInitModel(); |
|
272 | 2 | return $this->hasOne($profileClass, |
|
273 | 2 | [$profileModel->createdByAttribute => $this->guidAttribute])->inverseOf('user'); |
|
274 | } |
||
275 | |||
276 | /** |
||
277 | * @param $event |
||
278 | * @return mixed |
||
279 | */ |
||
280 | 48 | public function onGenerateId($event) |
|
281 | { |
||
282 | 48 | $sender = $event->sender; |
|
283 | /* @var $sender static */ |
||
284 | 48 | return $sender->generateId(); |
|
285 | } |
||
286 | |||
287 | /** |
||
288 | * @return array |
||
289 | */ |
||
290 | 53 | public function generateIdBehavior() |
|
291 | { |
||
292 | return [ |
||
293 | 53 | 'class' => AttributeBehavior::class, |
|
294 | 'attributes' => [ |
||
295 | 53 | ActiveRecord::EVENT_BEFORE_INSERT => $this->idAttribute, |
|
296 | ], |
||
297 | 53 | 'value' => [$this, 'onGenerateId'], |
|
298 | ]; |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * @return array |
||
303 | */ |
||
304 | 53 | public function behaviors() |
|
305 | { |
||
306 | 53 | $behaviors = parent::behaviors(); |
|
307 | 53 | $behavior = $this->generateIdBehavior(); |
|
308 | 53 | if (!empty($behavior)) { |
|
309 | 53 | $behaviors[] = $behavior; |
|
310 | } |
||
311 | 53 | return $behaviors; |
|
312 | } |
||
313 | |||
314 | /** |
||
315 | * @var string |
||
316 | */ |
||
317 | public static $idRegex = '/^\d{5,8}$/'; |
||
318 | |||
319 | /** |
||
320 | * @return array |
||
321 | */ |
||
322 | 2 | public function getIdRules() |
|
323 | { |
||
324 | return [ |
||
325 | 2 | [$this->idAttribute, 'safe'], |
|
326 | ]; |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * Friendly to IDE. |
||
331 | * @return UserQuery |
||
332 | */ |
||
333 | 48 | public static function find() |
|
334 | { |
||
335 | 48 | return parent::find(); |
|
336 | } |
||
337 | } |
||
338 |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.