Test Failed
Push — master ( 4863a3...b74686 )
by Alexey
04:36
created

Users::init()   D

Complexity

Conditions 18
Paths 56

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 342

Importance

Changes 0
Metric Value
cc 18
eloc 19
nc 56
nop 0
dl 0
loc 28
ccs 0
cts 23
cp 0
crap 342
rs 4.947
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Users module
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2015 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
class Users extends Module {
12
13
    public $cookiePrefix = '';
14
15
    public function init() {
16
        if (!empty($this->config['cookieSplit'])) {
17
            $this->cookiePrefix = \App::$cur->type;
18
        }
19
        \Users\User::$cur = new Users\User(array('group_id' => 1, 'role_id' => 1));
20
        if (!empty($_GET['invite_code']) && is_string($_GET['invite_code'])) {
21
            setcookie('invite_code', $_GET['invite_code'], time() + 360000, "/");
22
        }
23
        if (!App::$cur->db->connect) {
24
            return false;
25
        }
26
        if (isset($_GET['logout'])) {
27
            return $this->logOut();
28
        }
29
        if (isset($_GET['passre']) && filter_input(INPUT_GET, 'user_mail')) {
30
            $this->passre(trim(filter_input(INPUT_GET, 'user_mail')));
31
        }
32
        if (!empty($_GET['passrecont']) && filter_input(INPUT_GET, 'hash')) {
33
            $this->passrecont(filter_input(INPUT_GET, 'hash'));
34
        }
35
        if (isset($_POST['autorization']) && trim(filter_input(INPUT_POST, 'user_login')) && trim(filter_input(INPUT_POST, 'user_pass'))) {
36
            unset($_POST['autorization']);
37
            return $this->autorization(trim(filter_input(INPUT_POST, 'user_login')), trim(filter_input(INPUT_POST, 'user_pass')), strpos(filter_input(INPUT_POST, 'user_login'), '@') ? 'mail' : 'login', false, false, trim(filter_input(INPUT_POST, 'ref')));
38
        }
39
        if (!empty($_COOKIE[$this->cookiePrefix . '_user_session_hash']) && is_string($_COOKIE[$this->cookiePrefix . '_user_session_hash']) && !empty($_COOKIE[$this->cookiePrefix . '_user_id']) && is_string($_COOKIE[$this->cookiePrefix . '_user_id'])) {
40
            return $this->cuntinueSession($_COOKIE[$this->cookiePrefix . '_user_session_hash'], $_COOKIE[$this->cookiePrefix . '_user_id']);
41
        }
42
    }
43
44
    public function logOut($redirect = true) {
45
        if (!empty($_COOKIE[$this->cookiePrefix . "_user_session_hash"]) && !empty($_COOKIE[$this->cookiePrefix . "_user_id"])) {
46
            $session = Users\Session::get([
47
                ['user_id', $_COOKIE[$this->cookiePrefix . "_user_id"]],
48
                ['hash', $_COOKIE[$this->cookiePrefix . "_user_session_hash"]]
49
            ]);
50
            if ($session) {
51
                $session->delete();
52
            }
53
        }
54 View Code Duplication
        if (!headers_sent()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
            setcookie($this->cookiePrefix . "_user_session_hash", '', 0, "/");
56
            setcookie($this->cookiePrefix . "_user_id", '', 0, "/");
57
        }
58
        if ($redirect) {
59
            if (!empty($this->config['logoutUrl'][$this->app->type])) {
60
                Tools::redirect($this->config['logoutUrl'][$this->app->type]);
61
            }
62
            Tools::redirect('/', \I18n\Text::module('Users', 'Вы вышли из своего профиля'), 'success');
63
        }
64
    }
65
66
    public function cuntinueSession($hash, $userId) {
67
        $session = Users\Session::get([
68
            ['user_id', $userId],
69
            ['hash', $hash]
70
        ]);
71 View Code Duplication
        if (!$session) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
            if (!headers_sent()) {
73
                setcookie($this->cookiePrefix . "_user_session_hash", '', 0, "/");
74
                setcookie($this->cookiePrefix . "_user_id", '', 0, "/");
75
            }
76
            Tools::redirect('/', \I18n\Text::module('Users', 'Произошла непредвиденная ошибка при авторизации сессии'));
77
        }
78
        if ($session->user->id != $userId) {
79
            Tools::redirect('/', \I18n\Text::module('Users', 'Произошла непредвиденная ошибка при авторизации сессии'));
80
        }
81
        if ($session && $session->user && $session->user->blocked) {
82 View Code Duplication
            if (!headers_sent()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
                setcookie($this->cookiePrefix . "_user_session_hash", '', 0, "/");
84
                setcookie($this->cookiePrefix . "_user_id", '', 0, "/");
85
            }
86
            Msg::add(\I18n\Text::module('Users', 'Ваш аккаунт заблокирован'), 'info');
87
            return;
88
        }
89
        if ($session && $session->user && !$session->user->blocked) {
90
            if (!empty($this->config['needActivation']) && $session->user->activation) {
91 View Code Duplication
                if (!headers_sent()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
                    setcookie($this->cookiePrefix . "_user_session_hash", '', 0, "/");
93
                    setcookie($this->cookiePrefix . "_user_id", '', 0, "/");
94
                }
95
                Tools::redirect('/', 'Этот аккаунт ещё не активирован. <br />Если вы не получали письмо с ссылкой для активации, нажмите на - <a href = "/users/resendActivation/' . $session->user->id . '"><b>повторно выслать ссылку активации</b></a>');
96
            } elseif ($session->user->activation) {
97
                Msg::add('Этот аккаунт ещё не активирован, не все функции могут быть доступны. <br />Если вы не получали письмо с ссылкой для активации, нажмите на - <a href = "/users/resendActivation/' . $session->user->id . '"><b>повторно выслать ссылку активации</b></a>');
98
            }
99 View Code Duplication
            if (!$session->user->mail && !empty($this->config['noMailNotify'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
100
                Msg::add($this->config['noMailNotify']);
101
            }
102
            Users\User::$cur = $session->user;
103
            Users\User::$cur->date_last_active = 'CURRENT_TIMESTAMP';
104
            Users\User::$cur->save();
105 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
            if (!headers_sent()) {
107
                setcookie($this->cookiePrefix . "_user_session_hash", '', 0, "/");
108
                setcookie($this->cookiePrefix . "_user_id", '', 0, "/");
109
            }
110
            Msg::add(\I18n\Text::module('Users', 'needrelogin'), 'info');
111
        }
112
    }
113
114
    /**
115
     * @param string $user_mail
116
     */
117
    public function passre($user_mail) {
118
        $user = $this->get($user_mail, 'mail');
119 View Code Duplication
        if (!$user) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
            Msg::add(\I18n\Text::module('Users', 'mailnotfound', ['user_mail' => $user_mail]), 'danger');
121
            return false;
122
        }
123
        $passre = Users\Passre::get([['user_id', $user->id], ['status', 1]]);
124
        if ($passre) {
125
            $passre->status = 2;
126
            $passre->save();
127
        }
128
        $hash = $user->id . '_' . Tools::randomString(50);
129
        $passre = new Users\Passre(['user_id' => $user->id, 'status' => 1, 'hash' => $hash]);
130
        $passre->save();
131
        $domainRaw = App::$cur->getDomain();
132
        $domain = App::$cur->getDomain(true);
133
        $title = \I18n\Text::module('Users', 'Восстановление пароля на сайте ${domain}', ['domain' => $domain]);
134
        $text = \I18n\Text::module('Users', 'repassmailtext', ['domain' => $domain, 'hash' => $hash]);
135
        Tools::sendMail('noreply@' . $domainRaw, $user_mail, $title, $text);
136
        Tools::redirect('/', \I18n\Text::module('Users', 'На указанный почтовый ящик была выслана инструкция по восстановлению пароля'), 'success');
137
    }
138
139
    public function passrecont($hash) {
140
        $passre = Users\Passre::get([['hash', $hash]]);
141
        if ($passre) {
142
            if ($passre->status != 1) {
143
                Tools::redirect('/', 'Этот код восстановление более недействителен', 'danger');
144
            }
145
            $passre->status = 3;
146
            $passre->save();
147
            $pass = Tools::randomString(10);
148
            $user = Users\User::get($passre->user_id);
149
            $user->pass = $this->hashpass($pass);
150
            $user->save();
151
            $this->autorization($user->id, $pass, 'id', true, true);
152
            $domainRaw = App::$cur->getDomain();
153
            $domain = App::$cur->getDomain(true);
154
            $title = \I18n\Text::module('Users', 'Новый пароль на сайте ${domain}', ['domain' => $domain]);
155
            $text = \I18n\Text::module('Users', 'newpassmail', ['domain' => $domain, 'pass' => $pass]);
156
            Tools::sendMail('noreply@' . $domainRaw, $user->mail, $title, $text);
157
            Tools::redirect('/', \I18n\Text::module('Users', 'Вы успешно сбросили пароль и были авторизованы на сайте. На ваш почтовый ящик был выслан новый пароль'), 'success');
158
        }
159
    }
160
161
    public function autorization($login, $pass, $ltype = 'login', $noMsg = true, $skipErrorCheck = false, $redirect = '') {
162
        $user = $this->get($login, $ltype);
163
        if ($user && !$skipErrorCheck) {
164
            $lastSuccessLogin = \Users\User\LoginHistory::lastSuccessLogin($user->id);
165
            $where = [['user_id', $user->id]];
166
            if ($lastSuccessLogin) {
167
                $where[] = ['date_create', $lastSuccessLogin->date_create, '>'];
168
            }
169
            $loginHistoryErrorCount = \Users\User\LoginHistory::getCount(['where' => $where]);
170 View Code Duplication
            if ($loginHistoryErrorCount > 5) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
                Msg::add(\I18n\Text::module('Users', 'logintrylimit', ['user_mail' => $user->mail]), 'danger');
172
                return false;
173
            }
174
        }
175
        if ($user && $this->verifypass($pass, $user->pass) && !$user->blocked) {
176
            $loginHistory = new \Users\User\LoginHistory([
177
                'user_id' => $user->id,
178
                'ip' => $_SERVER['REMOTE_ADDR'],
179
                'success' => true
180
            ]);
181
            $loginHistory->save();
182
            if (!empty($this->config['needActivation']) && $user->activation) {
183
                Tools::redirect('/', 'Этот аккаунт ещё не активирован. <br />Если вы не получали письмо с ссылкой для активации, нажмите на - <a href = "/users/resendActivation/' . $user->id . '"><b>повторно выслать ссылку активации</b></a>');
184
            } elseif ($user->activation) {
185
                Msg::add('Этот аккаунт ещё не активирован, не все функции могут быть доступны. <br />Если вы не получали письмо с ссылкой для активации, нажмите на - <a href = "/users/resendActivation/' . $user->id . '"><b>повторно выслать ссылку активации</b></a>');
186
            }
187 View Code Duplication
            if (!$user->mail && !empty($this->config['noMailNotify'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
188
                Msg::add($this->config['noMailNotify']);
189
            }
190
            $this->newSession($user);
191
192
            Users\User::$cur = $user;
0 ignored issues
show
Documentation Bug introduced by
It seems like $user of type array or boolean or object<Model> is incompatible with the declared type object<Users\User> of property $cur.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
193
            Users\User::$cur->date_last_active = 'CURRENT_TIMESTAMP';
194
            Users\User::$cur->save();
195
            if (!$noMsg) {
196
                if (!empty($this->config['loginUrl'][$this->app->type]) && !$redirect) {
197
                    $redirect = $this->config['loginUrl'][$this->app->type];
198
                }
199
                Tools::redirect($redirect);
200
            }
201
202
            return true;
203
        }
204
        if (!$noMsg) {
205
            if ($user && $user->blocked) {
206
                Msg::add('Вы заблокированы', 'danger');
207
            } elseif ($user) {
208
                $loginHistory = new \Users\User\LoginHistory([
209
                    'user_id' => $user->id,
210
                    'ip' => $_SERVER['REMOTE_ADDR'],
211
                    'success' => false
212
                ]);
213
                $loginHistory->save();
214
                Msg::add(\I18n\Text::module('Users', 'loginfail', ['user_mail' => $user->mail]), 'danger');
215
            } else {
216
                Msg::add(\I18n\Text::module('Users', 'Данный почтовый ящик не зарегистрирован в системе'), 'danger');
217
            }
218
        }
219
220
        return false;
221
    }
222
223
    public function newSession($user) {
224
        $session = $this->createSession($user);
225
        if (!headers_sent()) {
226
            setcookie($this->cookiePrefix . "_user_session_hash", $session->hash, time() + 360000, "/");
227
            setcookie($this->cookiePrefix . "_user_id", $user->id, time() + 360000, "/");
228
        } else {
229
            Msg::add('Не удалось провести авторизацию. Попробуйте позже', 'info');
230
        }
231
    }
232
233
    public function createSession($user) {
234
        do {
235
            $hash = Tools::randomString(255);
236
        } while (Users\Session::get($hash, 'hash'));
237
238
        $session = new Users\Session([
239
            'user_id' => $user->id,
240
            'agent' => $_SERVER['HTTP_USER_AGENT'],
241
            'ip' => $_SERVER['REMOTE_ADDR'],
242
            'hash' => $hash
243
        ]);
244
        $session->save();
245
        return $session;
246
    }
247
248
    /**
249
     * Return user
250
     *
251
     * @param integer|string $idn
252
     * @param string $ltype
253
     * @return boolean|\Users\User
254
     */
255
    public function get($idn, $ltype = 'id') {
256
        if (!$idn)
257
            return false;
258
259
        if (is_numeric($idn) && $ltype != 'login')
260
            $user = Users\User::get($idn, 'id');
261
        elseif ($ltype == 'login')
262
            $user = Users\User::get($idn, 'login');
263
        else
264
            $user = Users\User::get($idn, 'mail');
265
        if (!$user)
266
            return [];
267
268
        return $user;
269
    }
270
271
    private function msgOrErr($err, $msg) {
272
        if ($msg) {
273
            Msg::add($err, 'danger');
274
            return false;
275
        }
276
        return ['success' => false, 'error' => $err];
277
278
    }
279
280
    public function registration($data, $autorization = false, $msg = true) {
281
282
        if (empty($data['user_mail'])) {
283
            return $this->msgOrErr('Вы не ввели E-mail', $msg);
284
        }
285
        $data['user_mail'] = trim($data['user_mail']);
286
        if (!filter_var($data['user_mail'], FILTER_VALIDATE_EMAIL)) {
287
            return $this->msgOrErr(\I18n\Text::module('Users', 'Вы ввели не корректный E-mail'), $msg);
288
289
        }
290
291
        $user = $this->get($data['user_mail'], 'mail');
292
        if ($user) {
293
            return $this->msgOrErr(\I18n\Text::module('Users', 'Введенный вами E-mail зарегистрирован в нашей системе, войдите или введите другой E-mail'), $msg);
294
        }
295
        if (empty($data['user_login'])) {
296
            $data['user_login'] = $data['user_mail'];
297
        }
298
        $data['user_login'] = trim($data['user_login']);
299
        $user = $this->get($data['user_login'], 'login');
300
        if ($user) {
301
            return $this->msgOrErr('Введенный вами логин зарегистрирован в нашей системе, войдите или введите другой логин', $msg);
302
        }
303
        if (empty($data['first_name'])) {
304
            $data['first_name'] = '';
305
        }
306
        if (empty($data['last_name'])) {
307
            $data['last_name'] = '';
308
        }
309
        if (!empty($data['user_name'])) {
310
            $data['first_name'] = $data['user_name'];
311
        }
312
        if (empty($data['user_city'])) {
313
            $data['user_city'] = '';
314
        }
315
        if (empty($data['user_birthday'])) {
316
            $data['user_birthday'] = '';
317
        }
318
        if (empty($data['user_phone'])) {
319
            $data['user_phone'] = '';
320
        }
321
        $invite_code = (!empty($data['invite_code']) ? $data['invite_code'] : (!empty($_POST['invite_code']) ? $_POST['invite_code'] : ((!empty($_COOKIE['invite_code']) ? $_COOKIE['invite_code'] : ((!empty($_GET['invite_code']) ? $_GET['invite_code'] : ''))))));
322
        if (!empty($invite_code)) {
323
            $invite = Users\User\Invite::get($invite_code, 'code');
324
            if (!$invite) {
325
                return $this->msgOrErr('Такой код приглашения не найден', $msg);
326
            }
327
            if ($invite->limit && !($invite->limit - $invite->count)) {
328
                return $this->msgOrErr('Лимит приглашений для данного кода исчерпан', $msg);
329
            }
330
            $data['parent_id'] = $invite->user_id;
331
            $inviter = $data['parent_id'];
332
            $invite->count++;
333
            $invite->save();
334
        }
335
        if (empty($data['parent_id']) && !empty($this->config['defaultPartner'])) {
336
            $data['parent_id'] = $this->config['defaultPartner'];
337
        }
338
        if (!empty($this->config['passwordManualSetup']) && !empty($data['user_pass'])) {
339
            if (empty($data['user_pass'][0])) {
340
                return $this->msgOrErr('Введите пароль', $msg);
341
            }
342
            if (empty($data['user_pass'][1])) {
343
                return $this->msgOrErr('Повторите ввод пароля', $msg);
344
            }
345
            if ($data['user_pass'][0] != $data['user_pass'][1]) {
346
                return $this->msgOrErr('Введенные пароли несовпадают', $msg);
347
            }
348
            $pass = $data['user_pass'][0];
349
        } else {
350
            $pass = Tools::randomString(10);
351
        }
352
353
        $user = new Users\User([
354
            'pass' => $this->hashpass($pass),
355
            'mail' => $data['user_mail'],
356
            'login' => htmlspecialchars($data['user_login']),
357
            'role_id' => 2,
358
            'group_id' => 2,
359
            'parent_id' => !empty($data['parent_id']) ? $data['parent_id'] : 0
360
        ]);
361
        if (!empty($this->config['needActivation'])) {
362
            $user->activation = Tools::randomString();
363
        }
364
        $user->save();
365
        if (!$user->id) {
366
            return $this->msgOrErr('Не удалось зарегистрировать', $msg);
367
        }
368
        $info = new \Users\User\Info([
369
            'user_id' => $user->id,
370
            'first_name' => htmlspecialchars($data['first_name']),
371
            'last_name' => htmlspecialchars($data['last_name']),
372
            'city' => htmlspecialchars($data['user_city']),
373
            'bday' => htmlspecialchars($data['user_birthday']),
374
            'phone' => htmlspecialchars($data['user_phone']),
375
            'photo_file_id' => !empty($_FILES['user_photo']['tmp_name']) ? $this->files->upload($_FILES['user_photo']) : 0
376
        ]);
377
        $info->save();
378
        if (isset($inviter)) {
379
            $this->AddUserActivity($inviter, 2, "У вас зарегистрировался новый партнер, {$info->first_name} {$info->last_name} (id: {$user->id}, email: {$user->mail})");
380
        }
381
        if ($autorization) {
382
            $this->autorization($data['user_mail'], $pass, 'mail');
383
        }
384
        if (!empty($this->config['needActivation'])) {
385
            $from = 'noreply@' . INJI_DOMAIN_NAME;
386
            $to = $data['user_mail'];
387
            $subject = 'Регистрация на сайте ' . idn_to_utf8(INJI_DOMAIN_NAME);
388
            $text = 'Вы были зарегистрированы на сайте ' . idn_to_utf8(INJI_DOMAIN_NAME) . '<br />для входа используйте ваш почтовый ящик в качестве логина и пароль: ' . $pass;
389
            $text .= '<br />';
390
            $text .= '<br />';
391
            $text .= 'Для активации вашего аккаунта перейдите по ссылке <a href = "http://' . INJI_DOMAIN_NAME . '/users/activation/' . $user->id . '/' . $user->activation . '">http://' . idn_to_utf8(INJI_DOMAIN_NAME) . '/users/activation/' . $user->id . '/' . $user->activation . '</a>';
392
            Tools::sendMail($from, $to, $subject, $text);
393
            if ($msg) {
394
                Msg::add('Вы были зарегистрированы. На указанный почтовый ящик был выслан ваш пароль и ссылка для активации', 'success');
395
            }
396
        } else {
397
            $from = 'noreply@' . INJI_DOMAIN_NAME;
398
            $to = $data['user_mail'];
399
            $subject = \I18n\Text::module('Users', 'Регистрация на сайте ${sitename}', ['sitename' => idn_to_utf8(INJI_DOMAIN_NAME)]);
400
            $text = \I18n\Text::module('Users', 'sucregmsg', [
401
                'sitename' => idn_to_utf8(INJI_DOMAIN_NAME),
402
                'pass' => $pass
403
            ]);
404
            Tools::sendMail($from, $to, $subject, $text);
405
            if ($msg) {
406
                Msg::add(\I18n\Text::module('Users', 'Вы были зарегистрированы. На указанный почтовый ящик был выслан ваш пароль'), 'success');
407
            }
408
        }
409
        return $user->id;
410
    }
411
412
    public function hashpass($pass) {
413
        return password_hash($pass, PASSWORD_DEFAULT);
414
    }
415
416
    public function verifypass($pass, $hash) {
417
        return password_verify($pass, $hash);
418
    }
419
420
    public function getUserPartners($user, $levelsCount = 0) {
421
        $return = [
422
            'users' => [],
423
            'levels' => [],
424
            'count' => 0,
425
            'lastLevel' => 0
426
        ];
427
        $userIds = $user->user_id;
428
        for ($i = 1; $i <= $levelsCount || !$levelsCount; $i++) {
429
            if (!$userIds && $levelsCount) {
430
                $return['levels'][$i] = [];
431
                continue;
432
            } elseif (!$userIds && !$levelsCount) {
433
                break;
434
            }
435
            $usersLevel = \Users\User::getList(['where' => [['parent_id', $userIds, 'IN']]]);
436
            $return['users'] += $usersLevel;
437
            $return['levels'][$i] = array_keys($usersLevel);
438
            $userIds = implode(',', $return['levels'][$i]);
439
            $return['lastLevel'] = $i;
440
        }
441
        $return['count'] = count($return['users']);
442
        return $return;
443
    }
444
445
    /**
446
     * @param integer $cat_id
447
     */
448
    public function addUserActivity($user_id, $cat_id, $text = '') {
449
        $ua = new Users\Activity([
450
            'user_id' => $user_id,
451
            'category_id' => $cat_id,
452
            'text' => $text,
453
        ]);
454
        $ua->save();
455
    }
456
}