Completed
Branch master (1f607b)
by Agel_Nash
08:24 queued 22s
created

modUsers::getRememberTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 7 and the first side effect is on line 2.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
require_once('MODx.php');
3
4
/**
5
 * Class modUsers
6
 */
7
class modUsers extends MODxAPI
1 ignored issue
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
8
{
9
    /**
10
     * @var array
11
     */
12
    protected $default_field = array(
13
        'user'      => array(
14
            'username' => '',
15
            'password' => '',
16
            'cachepwd' => ''
17
        ),
18
        'attribute' => array(
19
            'fullname'         => '',
20
            'role'             => '',
21
            'email'            => '',
22
            'phone'            => '',
23
            'mobilephone'      => '',
24
            'blocked'          => 0,
25
            'blockeduntil'     => 0,
26
            'blockedafter'     => 0,
27
            'logincount'       => 0,
28
            'lastlogin'        => 0,
29
            'thislogin'        => 0,
30
            'failedlogincount' => 0,
31
            'sessionid'        => '',
32
            'dob'              => 0,
33
            'gender'           => 0,
34
            'country'          => '',
35
            'state'            => '',
36
            'city'             => '',
37
            'street'           => '',
38
            'zip'              => '',
39
            'fax'              => '',
40
            'photo'            => '',
41
            'comment'          => '',
42
            'createdon'        => 0,
43
            'editedon'         => 0
44
        ),
45
        'hidden'    => array(
46
            'internalKey'
47
        )
48
    );
49
50
    /**
51
     * @var string
52
     */
53
    protected $givenPassword = '';
54
    protected $groupIds = array();
55
56
    /**
57
     * @var integer
58
     */
59
    private $rememberTime;
60
61
    /**
62
     * MODxAPI constructor.
63
     * @param DocumentParser $modx
64
     * @param bool $debug
65
     * @throws Exception
66
     */
67
    public function __construct(DocumentParser $modx, $debug = false)
68
    {
69
        $this->setRememberTime(60 * 60 * 24 * 365 * 5);
70
        parent::__construct($modx, $debug);
71
    }
72
73
    /**
74
     * @param $val
75
     * @return $this
76
     */
77
    protected function setRememberTime($val){
78
        $this->rememberTime = (int)$val;
79
        return $this;
80
    }
81
82
    /**
83
     * @return integer
84
     */
85
    public function getRememberTime(){
86
        return $this->rememberTime;
87
    }
88
89
    /**
90
     * @param $key
91
     * @return bool
92
     */
93
    public function issetField($key)
94
    {
95
        return (array_key_exists($key, $this->default_field['user']) || array_key_exists($key,
96
                $this->default_field['attribute']) || in_array($key, $this->default_field['hidden']));
97
    }
98
99
    /**
100
     * @param string $data
101
     * @return string|false
102
     */
103
    protected function findUser($data)
104
    {
105
        switch (true) {
106
            case (is_int($data) || ((int)$data > 0 && (string)intval($data) === $data)):
107
                $find = 'attribute.internalKey';
108
                break;
109
            case filter_var($data, FILTER_VALIDATE_EMAIL):
110
                $find = 'attribute.email';
111
                break;
112
            case is_scalar($data):
113
                $find = 'user.username';
114
                break;
115
            default:
116
                $find = false;
117
        }
118
119
        return $find;
120
    }
121
122
    /**
123
     * @param array $data
124
     * @return $this
125
     */
126
    public function create($data = array())
127
    {
128
        parent::create($data);
129
        $this->set('createdon', time());
130
131
        return $this;
132
    }
133
134
    /**
135
     * @param $id
136
     * @return $this
137
     */
138
    public function edit($id)
139
    {
140
        $id = is_scalar($id) ? trim($id) : '';
141
        if ($this->getID() != $id) {
142
            $this->close();
143
            $this->newDoc = false;
144
145
            if (!$find = $this->findUser($id)) {
146
                $this->id = null;
147
            } else {
148
                $this->set('editedon', time());
149
                $this->editQuery($find, $id);
150
                $this->id = empty($this->field['internalKey']) ? null : $this->get('internalKey');
151
                $this->store($this->toArray());
152
                unset($this->field['id']);
153
                unset($this->field['internalKey']);
154
            }
155
        }
156
157
        return $this;
158
    }
159
160
    /**
161
     * @param string $find
162
     * @param string $id
163
     */
164
    protected function editQuery($find, $id) {
165
        $result = $this->query("
166
            SELECT * from {$this->makeTable('web_user_attributes')} as attribute
167
            LEFT JOIN {$this->makeTable('web_users')} as user ON user.id=attribute.internalKey
168
            WHERE BINARY {$find}='{$this->escape($id)}'
169
        ");
170
        $this->field = $this->modx->db->getRow($result);
171
    }
172
173
    /**
174
     * @param string $key
175
     * @param $value
176
     * @return $this
177
     */
178
    public function set($key, $value)
179
    {
180
        if (is_scalar($value) && is_scalar($key) && !empty($key)) {
181
            switch ($key) {
182
                case 'password':
183
                    $this->givenPassword = $value;
184
                    $value = $this->getPassword($value);
185
                    break;
186
                case 'sessionid':
187
                    session_regenerate_id(false);
188
                    $value = session_id();
189
                    if ($mid = $this->modx->getLoginUserID('mgr')) {
190
                        $this->modx->db->query("UPDATE {$this->makeTable('active_user_locks')} SET `sid`='{$value}' WHERE `internalKey`={$mid}");
191
                        $this->modx->db->query("UPDATE {$this->makeTable('active_user_sessions')} SET `sid`='{$value}' WHERE `internalKey`={$mid}");
192
                        $this->modx->db->query("UPDATE {$this->makeTable('active_users')} SET `sid`='{$value}' WHERE `internalKey`={$mid}");
193
                    }
194
                    break;
195
                case 'editedon':
196
                case 'createdon':
197
                    $value = $this->getTime($value);
198
                    break;
199
            }
200
            $this->field[$key] = $value;
201
        }
202
203
        return $this;
204
    }
205
206
    /**
207
     * @param $pass
208
     * @return string
209
     */
210
    public function getPassword($pass)
211
    {
212
        return md5($pass);
213
    }
214
215
    /**
216
     * @param bool $fire_events
217
     * @param bool $clearCache
218
     * @return bool|int|null|void
219
     */
220
    public function save($fire_events = false, $clearCache = false)
221
    {
222
        if ($this->get('email') == '' || $this->get('username') == '' || $this->get('password') == '') {
223
            $this->log['EmptyPKField'] = 'Email, username or password is empty <pre>' . print_r($this->toArray(),
224
                    true) . '</pre>';
225
226
            return false;
227
        }
228
229
        if (!$this->checkUnique('web_users', 'username')) {
230
            $this->log['UniqueUsername'] = 'username not unique <pre>' . print_r($this->get('username'),
231
                    true) . '</pre>';
232
233
            return false;
234
        }
235
236
        if (!$this->checkUnique('web_user_attributes', 'email', 'internalKey')) {
237
            $this->log['UniqueEmail'] = 'Email not unique <pre>' . print_r($this->get('email'), true) . '</pre>';
238
239
            return false;
240
        }
241
        $this->set('sessionid', '');
242
        $fld = $this->toArray();
243
        foreach ($this->default_field['user'] as $key => $value) {
244
            $tmp = $this->get($key);
245
            if ($this->newDoc && (!is_int($tmp) && $tmp == '')) {
246
                $this->field[$key] = $value;
247
            }
248
            $this->Uset($key, 'user');
249
            unset($fld[$key]);
250
        }
251
        if (!empty($this->set['user'])) {
252
            if ($this->newDoc) {
253
                $SQL = "INSERT into {$this->makeTable('web_users')} SET " . implode(', ', $this->set['user']);
254
            } else {
255
                $SQL = "UPDATE {$this->makeTable('web_users')} SET " . implode(', ',
256
                        $this->set['user']) . " WHERE id = " . $this->id;
257
            }
258
            $this->query($SQL);
259
        }
260
261
        if ($this->newDoc) {
262
            $this->id = $this->modx->db->getInsertId();
263
        }
264
265
        $this->saveQuery($fld);
266
        unset($fld['id']);
267
268
        foreach ($fld as $key => $value) {
269
            if ($value == '' || !$this->isChanged($key)) {
270
                continue;
271
            }
272
            $result = $this->query("SELECT `setting_value` FROM {$this->makeTable('web_user_settings')} WHERE `webuser` = '{$this->id}' AND `setting_name` = '{$key}'");
273
            if ($this->modx->db->getRecordCount($result) > 0) {
274
                $this->query("UPDATE {$this->makeTable('web_user_settings')} SET `setting_value` = '{$value}' WHERE `webuser` = '{$this->id}' AND `setting_name` = '{$key}';");
275
            } else {
276
                $this->query("INSERT into {$this->makeTable('web_user_settings')} SET `webuser` = {$this->id},`setting_name` = '{$key}',`setting_value` = '{$value}';");
277
            }
278
        }
279
        if (!$this->newDoc && $this->givenPassword) {
280
            $this->invokeEvent('OnWebChangePassword', array(
281
                'userObj'      => $this,
282
                'userid'       => $this->id,
283
                'user'         => $this->toArray(),
284
                'userpassword' => $this->givenPassword,
285
                'internalKey'  => $this->id,
286
                'username'     => $this->get('username')
287
            ), $fire_events);
288
        }
289
290
        if (!empty($this->groupIds)) $this->setUserGroups($this->id, $this->groupIds);
291
292
        $this->invokeEvent('OnWebSaveUser', array(
293
            'userObj' => $this,
294
            'mode'    => $this->newDoc ? "new" : "upd",
295
            'id'      => $this->id,
296
            'user'    => $this->toArray()
297
        ), $fire_events);
298
299
        if ($clearCache) {
300
            $this->clearCache($fire_events);
301
        }
302
303
        return $this->id;
304
    }
305
306
    /**
307
     * @param  array  $fld
308
     */
309
    protected function saveQuery(array &$fld) {
310
        foreach ($this->default_field['attribute'] as $key => $value) {
311
            $tmp = $this->get($key);
312
            if ($this->newDoc && (!is_int($tmp) && $tmp == '')) {
313
                $this->field[$key] = $value;
314
            }
315
            $this->Uset($key, 'attribute');
316
            unset($fld[$key]);
317
        }
318
        if (!empty($this->set['attribute'])) {
319
            if ($this->newDoc) {
320
                $this->set('internalKey', $this->id)->Uset('internalKey', 'attribute');
321
                $SQL = "INSERT into {$this->makeTable('web_user_attributes')} SET " . implode(', ',
322
                        $this->set['attribute']);
323
            } else {
324
                $SQL = "UPDATE {$this->makeTable('web_user_attributes')} SET " . implode(', ',
325
                        $this->set['attribute']) . " WHERE  internalKey = " . $this->getID();
326
            }
327
            $this->query($SQL);
328
        }
329
    }
330
331
    /**
332
     * @param $ids
333
     * @param bool $fire_events
334
     * @return bool|null|void
335
     */
336
    public function delete($ids, $fire_events = false)
337
    {
338
        if ($this->edit($ids)) {
339
            $flag = $this->deleteQuery();
340
            $this->query("DELETE FROM {$this->makeTable('web_user_settings')} WHERE webuser='{$this->getID()}'");
341
            $this->query("DELETE FROM {$this->makeTable('web_groups')} WHERE webuser='{$this->getID()}'");
342
            $this->invokeEvent('OnWebDeleteUser', array(
343
                'userObj'     => $this,
344
                'userid'      => $this->getID(),
345
                'internalKey' => $this->getID(),
346
                'username'    => $this->get('username'),
347
                'timestamp'   => time()
348
            ), $fire_events);
349
        } else {
350
            $flag = false;
351
        }
352
        $this->close();
353
354
        return $flag;
355
    }
356
357
    protected function deleteQuery() {
358
        return $this->query("
359
          DELETE user,attribute FROM {$this->makeTable('web_user_attributes')} as attribute
360
            LEFT JOIN {$this->makeTable('web_users')} as user ON user.id=attribute.internalKey
361
            WHERE attribute.internalKey='{$this->escape($this->getID())}'");
362
    }
363
364
    /**
365
     * @param int $id
366
     * @param bool|integer $fulltime
367
     * @param string $cookieName
368
     * @param bool $fire_events
369
     * @return bool
370
     */
371
    public function authUser($id = 0, $fulltime = true, $cookieName = 'WebLoginPE', $fire_events = false)
372
    {
373
        $flag = false;
374
        if (null === $this->getID() && $id) {
375
            $this->edit($id);
376
        }
377
        if (null !== $this->getID()) {
378
            $flag = true;
379
            $this->save(false);
380
            $this->SessionHandler('start', $cookieName, $fulltime);
381
            $this->invokeEvent("OnWebLogin", array(
382
                'userObj'      => $this,
383
                'userid'       => $this->getID(),
384
                'username'     => $this->get('username'),
385
                'userpassword' => $this->givenPassword,
386
                'rememberme'   => $fulltime
387
            ), $fire_events);
388
        }
389
390
        return $flag;
391
    }
392
393
    /**
394
     * @param int $id
395
     * @return bool
396
     */
397
    public function checkBlock($id = 0)
398
    {
399
        $tmp = clone $this;
400
        if ($id && $tmp->getID() != $id) {
401
            $tmp->edit($id);
402
        }
403
        $now = time();
404
405
        $b = $tmp->get('blocked');
406
        $bu = $tmp->get('blockeduntil');
407
        $ba = $tmp->get('blockedafter');
408
        $flag = (($b && !$bu && !$ba) || ($bu && $now < $bu) || ($ba && $now > $ba));
409
        unset($tmp);
410
411
        return $flag;
412
    }
413
414
    /**
415
     * @param $id
416
     * @param $password
417
     * @param $blocker
418
     * @param bool $fire_events
419
     * @return bool
420
     */
421
    public function testAuth($id, $password, $blocker, $fire_events = false)
422
    {
423
        $tmp = clone $this;
424
        if ($id && $tmp->getID() != $id) {
425
            $tmp->edit($id);
426
        }
427
428
        $flag = $pluginFlag = false;
429
        if (
430
            (null !== $tmp->getID()) && (!$blocker || ($blocker && !$tmp->checkBlock($id)))
431
        ) {
432
            $eventResult = $this->getInvokeEventResult('OnWebAuthentication', array(
433
                'userObj'       => $this,
434
                'userid'        => $tmp->getID(),
435
                'username'      => $tmp->get('username'),
436
                'userpassword'  => $password,
437
                'savedpassword' => $tmp->get('password')
438
            ), $fire_events);
439
            if (is_array($eventResult)) {
440
                foreach ($eventResult as $result) {
441
                    $pluginFlag = (bool)$result;
442
                }
443
            } else {
444
                $pluginFlag = (bool)$eventResult;
445
            }
446
            if (!$pluginFlag) {
447
                $flag = ($tmp->get('password') == $tmp->getPassword($password));
448
            }
449
        }
450
        unset($tmp);
451
452
        return $flag || $pluginFlag;
453
    }
454
455
    /**
456
     * @param bool|integer $fulltime
457
     * @param string $cookieName
458
     * @return bool
459
     */
460
    public function AutoLogin($fulltime = true, $cookieName = 'WebLoginPE', $fire_events = null)
1 ignored issue
show
Coding Style introduced by
AutoLogin uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
461
    {
462
        $flag = false;
463
        if (isset($_COOKIE[$cookieName])) {
464
            $cookie = explode('|', $_COOKIE[$cookieName], 4);
465
            if (isset($cookie[0], $cookie[1], $cookie[2]) && strlen($cookie[0]) == 32 && strlen($cookie[1]) == 32) {
466
                if (!$fulltime && isset($cookie[4])) {
467
                    $fulltime = (int)$cookie[4];
468
                }
469
                $this->close();
470
                $q = $this->modx->db->query("SELECT id FROM " . $this->makeTable('web_users') . " WHERE md5(username)='{$this->escape($cookie[0])}'");
471
                $id = $this->modx->db->getValue($q);
472
                if (
473
                    $this->edit($id)
474
                    && null !== $this->getID()
475
                    && $this->get('password') == $cookie[1]
476
                    && $this->get('sessionid') == $cookie[2]
477
                    && !$this->checkBlock($this->getID())
478
                ) {
479
                    $flag = $this->authUser($this->getID(), $fulltime, $cookieName, $fire_events);
480
481
                }
482
            }
483
        }
484
485
        return $flag;
486
    }
487
488
    /**
489
     * @param string $cookieName
490
     * @param bool $fire_events
491
     */
492
    public function logOut($cookieName = 'WebLoginPE', $fire_events = false)
1 ignored issue
show
Coding Style introduced by
logOut uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
493
    {
494
        if (!$uid = $this->modx->getLoginUserID('web')) {
495
            return;
496
        }
497
        $params = array(
498
            'username'    => $_SESSION['webShortname'],
499
            'internalKey' => $uid,
500
            'userid'      => $uid // Bugfix by TS
501
        );
502
        $this->invokeEvent('OnBeforeWebLogout', $params, $fire_events);
503
        $this->SessionHandler('destroy', $cookieName ? $cookieName : 'WebLoginPE');
504
        $this->invokeEvent('OnWebLogout', $params, $fire_events);
505
    }
506
507
    /**
508
     * SessionHandler
509
     * Starts the user session on login success. Destroys session on error or logout.
510
     *
511
     * @param string $directive ('start' or 'destroy')
512
     * @param string $cookieName
513
     * @param bool|integer $remember
514
     * @return modUsers
515
     * @author Raymond Irving
516
     * @author Scotty Delicious
517
     *
518
     * remeber может быть числом в секундах
519
     */
520
    protected function SessionHandler($directive, $cookieName, $remember = true)
2 ignored issues
show
Coding Style introduced by
SessionHandler uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
SessionHandler uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
521
    {
522
        switch ($directive) {
523
            case 'start':
524
                if ($this->getID() !== null) {
525
                    $_SESSION['webShortname'] = $this->get('username');
526
                    $_SESSION['webFullname'] = $this->get('fullname');
527
                    $_SESSION['webEmail'] = $this->get('email');
528
                    $_SESSION['webValidated'] = 1;
529
                    $_SESSION['webInternalKey'] = $this->getID();
530
                    $_SESSION['webValid'] = base64_encode($this->get('password'));
531
                    $_SESSION['webUser'] = base64_encode($this->get('username'));
532
                    $_SESSION['webFailedlogins'] = $this->get('failedlogincount');
533
                    $_SESSION['webLastlogin'] = $this->get('lastlogin');
534
                    $_SESSION['webnrlogins'] = $this->get('logincount');
535
                    $_SESSION['webUsrConfigSet'] = array();
536
                    $_SESSION['webUserGroupNames'] = $this->getUserGroups();
537
                    $_SESSION['webDocgroups'] = $this->getDocumentGroups();
538
                    if (!empty($remember)) {
539
                        $this->setAutoLoginCookie($cookieName, $remember);
540
                    }
541
                }
542
                break;
543
            case 'destroy':
544
                if (isset($_SESSION['mgrValidated'])) {
545
                    unset($_SESSION['webShortname']);
546
                    unset($_SESSION['webFullname']);
547
                    unset($_SESSION['webEmail']);
548
                    unset($_SESSION['webValidated']);
549
                    unset($_SESSION['webInternalKey']);
550
                    unset($_SESSION['webValid']);
551
                    unset($_SESSION['webUser']);
552
                    unset($_SESSION['webFailedlogins']);
553
                    unset($_SESSION['webLastlogin']);
554
                    unset($_SESSION['webnrlogins']);
555
                    unset($_SESSION['webUsrConfigSet']);
556
                    unset($_SESSION['webUserGroupNames']);
557
                    unset($_SESSION['webDocgroups']);
558
559
                    setcookie($cookieName, '', time() - 60, MODX_BASE_URL);
560
                } else {
561
                    if (isset($_COOKIE[session_name()])) {
562
                        setcookie(session_name(), '', time() - 60, MODX_BASE_URL);
563
                    }
564
                    setcookie($cookieName, '', time() - 60, MODX_BASE_URL);
565
                    session_destroy();
566
                }
567
                break;
568
        }
569
570
        return $this;
571
    }
572
573
    /**
574
     * @return bool
575
     */
576
    public function isSecure()
577
    {
578
        $out = $this->modxConfig('server_protocol') == 'http' ? false : true;
579
580
        return $out;
581
    }
582
583
    /**
584
     * @param $cookieName
585
     * @param bool|integer $remember
586
     * @return $this
587
     */
588
    public function setAutoLoginCookie($cookieName, $remember = true)
589
    {
590
        if (!empty($cookieName) && $this->getID() !== null) {
591
            $secure = $this->isSecure();
592
            $remember = is_bool($remember) ? $this->getRememberTime() : (int)$remember;
593
            $cookieValue = array(md5($this->get('username')), $this->get('password'), $this->get('sessionid'), $remember);
594
            $cookieValue = implode('|', $cookieValue);
595
            $cookieExpires = time() + $remember;
596
            setcookie($cookieName, $cookieValue, $cookieExpires, MODX_BASE_URL, '', $secure, true);
597
        }
598
599
        return $this;
600
    }
601
602
    /**
603
     * @param int $userID
604
     * @return array
605
     */
606
    public function getDocumentGroups($userID = 0)
607
    {
608
        $out = array();
609
        $user = $this->switchObject($userID);
610
        if (null !== $user->getID()) {
611
            $web_groups = $this->modx->getFullTableName('web_groups');
612
            $webgroup_access = $this->modx->getFullTableName('webgroup_access');
613
614
            $sql = "SELECT `uga`.`documentgroup` FROM {$web_groups} as `ug`
615
                INNER JOIN {$webgroup_access} as `uga` ON `uga`.`webgroup`=`ug`.`webgroup`
616
                WHERE `ug`.`webuser` = " . $user->getID();
617
            $out = $this->modx->db->getColumn('documentgroup', $this->query($sql));
618
619
        }
620
        unset($user);
621
622
        return $out;
623
    }
624
625
    /**
626
     * @param int $userID
627
     * @return array
628
     */
629
    public function getUserGroups($userID = 0)
630
    {
631
        $out = array();
632
        $user = $this->switchObject($userID);
633
        if (null !== $user->getID()) {
634
            $web_groups = $this->makeTable('web_groups');
635
            $webgroup_names = $this->makeTable('webgroup_names');
636
637
            $rs = $this->query("SELECT `ug`.`webgroup`, `ugn`.`name` FROM {$web_groups} as `ug`
638
                INNER JOIN {$webgroup_names} as `ugn` ON `ugn`.`id`=`ug`.`webgroup`
639
                WHERE `ug`.`webuser` = " . $user->getID());
640
            while ($row = $this->modx->db->getRow($rs)) {
641
                $out[$row['webgroup']] = $row['name'];
642
            }
643
        }
644
        unset($user);
645
646
        return $out;
647
    }
648
649
    /**
650
     * @param int $userID
651
     * @param array $groupIds
652
     * @return $this
653
     */
654
    public function setUserGroups($userID = 0, $groupIds = array())
655
    {
656
        if (!is_array($groupIds)) return $this;
657
        if ($this->newDoc && $userID == 0) {
658
            $this->groupIds = $groupIds;
659
        } else {
660
            $user = $this->switchObject($userID);
661
            if ($uid = $user->getID()) {
662
                foreach ($groupIds as $gid) {
663
                    $this->query("REPLACE INTO {$this->makeTable('web_groups')} (`webgroup`, `webuser`) VALUES ('{$gid}', '{$uid}')");
664
                }
665
                if (!$this->newDoc) {
666
                    $groupIds = empty($groupIds) ? '0' : implode(',', $groupIds);
667
                    $this->query("DELETE FROM {$this->makeTable('web_groups')} WHERE `webuser`={$uid} AND `webgroup` NOT IN ({$groupIds})");
668
                }
669
            }
670
            unset($user);
671
            $this->groupIds = array();
672
        }
673
674
        return $this;
675
    }
676
}
677