GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — 2.8 ( 651d2c...3866ce )
by Thorsten
18:13
created

PMF_User::createUser()   D

Complexity

Conditions 13
Paths 141

Size

Total Lines 74
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 42
nc 141
nop 3
dl 0
loc 74
rs 4.9869
c 0
b 0
f 0

How to fix   Long Method    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
 * Creates a new user object.
4
 *
5
 * A user are recognized by the session-id using getUserBySessionId(), by his
6
 * using getUserById() or by his nickname (login) using getUserByLogin(). New
7
 * are created using createNewUser().
8
 *
9
 * PHP Version 5.3
10
 *
11
 * This Source Code Form is subject to the terms of the Mozilla Public License,
12
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
13
 * obtain one at http://mozilla.org/MPL/2.0/.
14
 *
15
 * @category  phpMyFAQ
16
 * @package   User
17
 * @author    Lars Tiedemann <[email protected]>
18
 * @author    Thorsten Rinne <[email protected]>
19
 * @author    Sarah Hermann <[email protected]>
20
 * @copyright 2005-2016 phpMyFAQ Team
21
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
22
 * @link      http://www.phpmyfaq.de
23
 * @since     2005-09-17
24
 */
25
26
if (!defined('IS_VALID_PHPMYFAQ')) {
27
    exit();
28
}
29
30
if (!defined('PMF_ENCRYPTION_TYPE')) {
31
    define('PMF_ENCRYPTION_TYPE', 'md5'); // Fallback to md5()
32
}
33
34
/**
35
 * User
36
 *
37
 * @category  phpMyFAQ
38
 * @package   User
39
 * @author    Lars Tiedemann <[email protected]>
40
 * @author    Thorsten Rinne <[email protected]>
41
 * @author    Sarah Hermann <[email protected]>
42
 * @copyright 2005-2016 phpMyFAQ Team
43
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
44
 * @link      http://www.phpmyfaq.de
45
 * @since     2005-09-17
46
 */
47
class PMF_User
48
{
49
    const ERROR_UNDEFINED_PARAMETER = 'Following parameter must to be defined: ';
50
    const ERROR_USER_ADD = 'Account could not be created. ';
51
    const ERROR_USER_CANNOT_CREATE_USER = 'User account could not be created. ';
52
    const ERROR_USER_CANNOT_CREATE_USERDATA = 'Entry for user data could not be created. ';
53
    const ERROR_USER_CANNOT_DELETE_USER = 'User account could not be deleted. ';
54
    const ERROR_USER_CANNOT_DELETE_USERDATA = 'Entry for user data could not be deleted. ';
55
    const ERROR_USER_CANNOT_UPDATE_USERDATA = 'Entry for user data could not be updated. ';
56
    const ERROR_USER_CHANGE = 'Account could not be updated. ';
57
    const ERROR_USER_DELETE = 'Account could not be deleted. ';
58
    const ERROR_USER_INCORRECT_LOGIN = 'Specified login could not be found. ';
59
    const ERROR_USER_INCORRECT_PASSWORD = 'Specified password is not correct.';
60
    const ERROR_USER_INVALID_STATUS = 'Undefined user status.';
61
    const ERROR_USER_LOGINNAME_TOO_SHORT = 'The chosen loginname is too short.';
62
    const ERROR_USER_LOGIN_NOT_UNIQUE = 'Specified login name already exists. ';
63
    const ERROR_USER_LOGIN_INVALID = 'The chosen login is invalid. A valid login has at least four characters. Only letters, numbers and underscore _ are allowed. The first letter must be a letter. ';
64
    const ERROR_USER_NO_AUTH = 'No authentication method specified. ';
65
    const ERROR_USER_NO_DB = 'No database specified.';
66
    const ERROR_USER_NO_PERM = 'No permission container specified.';
67
    const ERROR_USER_NO_USERID = 'No user-ID found. ';
68
    const ERROR_USER_NO_USERLOGINDATA = 'No user login data found. ';
69
    const ERROR_USER_NOT_FOUND = 'User account could not be found. ';
70
    const ERROR_USER_NOWRITABLE = 'No authentication object is writable. ';
71
    const ERROR_USER_NO_LOGIN_DATA = 'A username and password must be provided. ';
72
73
    const STATUS_USER_PROTECTED = 'User account is protected. ';
74
    const STATUS_USER_BLOCKED = 'User account is blocked. ';
75
    const STATUS_USER_ACTIVE = 'User account is active. ';
76
77
    // --- ATTRIBUTES ---
78
79
    /**
80
     * Permission container
81
     *
82
     * @var PMF_Perm
83
     */
84
    public $perm = null;
85
86
    /**
87
     * User-data storage container
88
     *
89
     * @var PMF_User_UserData
90
     */
91
    public $userdata = null;
92
93
    /**
94
     * Default Authentication properties
95
     *
96
     * @var array
97
     */
98
    private $authData = array(
99
        'authSource' => array(
100
            'name' => 'db',
101
            'type' => 'local'
102
        ),
103
        'encType'    => PMF_ENCRYPTION_TYPE,
104
        'readOnly'   => false
105
    );
106
107
    /**
108
     * Public array that contains error messages.
109
     *
110
     * @var array
111
     */
112
    public $errors = array();
113
114
    /**
115
     * authentication container
116
     *
117
     * @var array
118
     */
119
    protected $authContainer = array();
120
    
121
    /**
122
     * login string
123
     *
124
     * @var string
125
     */
126
    private $login = '';
127
128
    /**
129
     * minimum length of login string (default: 2)
130
     *
131
     * @var int
132
     */
133
    private $loginMinLength = 2;
134
135
    /**
136
     * regular expression to find invalid login strings
137
     * (default: /^[a-z0-9][\w\.\-@]+/i )
138
     *
139
     * @var string
140
     */
141
    private $validUsername = '/^[a-z0-9][\w\.\-@]+/i';
142
    
143
    /**
144
     * user ID
145
     *
146
     * @var integer
147
     */
148
    private $userId = -1;
149
    
150
    /**
151
     * Status of user
152
     *
153
     * @var string
154
     */
155
    private $status = '';
156
157
    /**
158
     * array of allowed values for status
159
     *
160
     * @var array
161
     */
162
    private $allowedStatus = array(
163
        'active'    => self::STATUS_USER_ACTIVE,
164
        'blocked'   => self::STATUS_USER_BLOCKED,
165
        'protected' => self::STATUS_USER_PROTECTED
166
    );
167
168
    /**
169
     * Configuration
170
     *
171
     * @var PMF_Configuration
172
     */
173
    protected $config = null;
174
175
    /**
176
     * Constructor
177
     *
178
     * @param PMF_Configuration $config
179
     *
180
     * @return PMF_User
181
     */
182
    public function __construct(PMF_Configuration $config)
183
    {
184
        $this->config = $config;
185
186
        $permLevel = $this->config->get('security.permLevel');
187
        $perm      = PMF_Perm::selectPerm($permLevel, $this->config);
188
        if (!$this->addPerm($perm)) {
189
            return;
190
        }
191
        
192
        // authentication objects
193
        // always make a 'local' $auth object (see: $authData)
194
        $this->authContainer = array();
195
        $auth = new PMF_Auth($this->config);
196
        $authLocal = $auth->selectAuth($this->getAuthSource('name'));
197
        $authLocal->selectEncType($this->getAuthData('encType'));
198
        $authLocal->setReadOnly($this->getAuthData('readOnly'));
199
        if (!$this->addAuth($authLocal, $this->getAuthSource('type'))) {
200
            return;
201
        }
202
        
203
        // additionally, set given $auth objects
204
        if (count($auth) > 0) {
205
            foreach ($auth as $name => $authObject) {
206
                if (!$this->addAuth($authObject, $name)) {
207
                    break;
208
                }
209
            }
210
        }
211
        // user data object
212
        $this->userdata = new PMF_User_UserData($this->config);
213
    }
214
215
216
    // --- OPERATIONS ---
217
218
    /**
219
     * adds a permission object to the user.
220
     *
221
     * @param  PMF_Perm $perm Permission object
222
     * @return boolean
223
     */
224
    public function addPerm(PMF_Perm $perm)
225
    {
226
        if ($this->checkPerm($perm)) {
227
            $this->perm = $perm;
228
            return true;
229
        }
230
        $this->perm = null;
231
        return false;
232
    }
233
234
    /**
235
     * Returns the User ID of the user.
236
     *
237
     * @return integer
238
     */
239
    public function getUserId()
240
    {
241
        if (isset($this->userId) && is_int($this->userId)) {
242
            return (int)$this->userId;
243
        }
244
        $this->userId  = -1;
245
        $this->errors[] = self::ERROR_USER_NO_USERID;
246
        
247
        return -1;
248
    }
249
250
    /**
251
     * Loads basic user information from the database selecting the user with
252
     * specified user-ID.
253
     *
254
     * @param  integer $userId            User ID
255
     * @param  boolean $allowBlockedUsers Allow blocked users as well, e.g. in admin
256
     *
257
     * @return bool
258
     */
259
    public function getUserById($userId, $allowBlockedUsers = false)
260
    {
261
        $select = sprintf("
262
            SELECT
263
                user_id,
264
                login,
265
                account_status
266
            FROM
267
                %sfaquser
268
            WHERE
269
                user_id = %d " . ( $allowBlockedUsers ? '' : "AND account_status != 'blocked'"),
270
            PMF_Db::getTablePrefix(),
271
            (int) $userId
272
        );
273
274
        $res = $this->config->getDb()->query($select);
275 View Code Duplication
        if ($this->config->getDb()->numRows($res) != 1) {
276
            $this->errors[] = self::ERROR_USER_NO_USERID . 'error(): ' . $this->config->getDb()->error();
277
            return false;
278
        }
279
        $user          = $this->config->getDb()->fetchArray($res);
280
        $this->userId = (int)    $user['user_id'];
281
        $this->login   = (string)$user['login'];
282
        $this->status  = (string)$user['account_status'];
283
        
284
        // get encrypted password
285
        // @todo: Add a getEncPassword method to the Auth* classes for the (local and remote) Auth Sources.
286
        if ('db' === $this->getAuthSource('name')) {
287
            $select = sprintf("
288
                SELECT
289
                    pass
290
                FROM
291
                    %sfaquserlogin
292
                WHERE
293
                    login = '%s'",
294
                PMF_Db::getTablePrefix(),
295
                $this->login
296
            );
297
                
298
            $res = $this->config->getDb()->query($select);
299 View Code Duplication
            if ($this->config->getDb()->numRows($res) != 1) {
300
                $this->errors[] = self::ERROR_USER_NO_USERLOGINDATA . 'error(): ' . $this->config->getDb()->error();
301
                return false;
302
            }
303
        }
304
        // get user-data
305
        if (!$this->userdata instanceof PMF_User_UserData) {
306
            $this->userdata = new PMF_User_UserData($this->config);
307
        }
308
        $this->userdata->load($this->getUserId());
309
        return true;
310
    }
311
312
    /**
313
     * loads basic user information from the database selecting the user with
314
     * specified login.
315
     *
316
     * @param  string $login       Login name
317
     * @param  bool   $raiseError Raise error?
318
     * @return bool
319
     */
320 View Code Duplication
    public function getUserByLogin($login, $raiseError = true)
321
    {
322
        $select = sprintf("
323
            SELECT
324
                user_id,
325
                login,
326
                account_status
327
            FROM
328
                %sfaquser
329
            WHERE
330
                login = '%s'",
331
            PMF_Db::getTablePrefix(),
332
            $this->config->getDb()->escape($login)
333
        );
334
        
335
        $res = $this->config->getDb()->query($select);
336
        if ($this->config->getDb()->numRows($res) !== 1) {
337
            if ($raiseError) {
338
339
                $this->errors[] = self::ERROR_USER_INCORRECT_LOGIN;
340
            }
341
            return false;
342
        }
343
        $user = $this->config->getDb()->fetchArray($res);
344
        $this->userId  = (int)    $user['user_id'];
345
        $this->login   = (string) $user['login'];
346
        $this->status  = (string) $user['account_status'];
347
348
        // get user-data
349
        if (!$this->userdata instanceof PMF_User_UserData) {
350
            $this->userdata = new PMF_User_UserData($this->config);
351
        }
352
        $this->userdata->load($this->getUserId());
353
        return true;
354
    }
355
356
    /**
357
     * loads basic user information from the database selecting the user with
358
     * specified cookie information.
359
     *
360
     * @param string $cookie
361
     *
362
     * @return boolean
363
     */
364 View Code Duplication
    public function getUserByCookie($cookie)
365
    {
366
        $select = sprintf("
367
            SELECT
368
                user_id,
369
                login,
370
                account_status
371
            FROM
372
                %sfaquser
373
            WHERE
374
                remember_me = '%s' AND account_status != 'blocked'",
375
            PMF_Db::getTablePrefix(),
376
            $this->config->getDb()->escape($cookie)
377
        );
378
379
        $res = $this->config->getDb()->query($select);
380
        if ($this->config->getDb()->numRows($res) !== 1) {
381
            $this->errors[] = self::ERROR_USER_INCORRECT_LOGIN;
382
            return false;
383
        }
384
        $user = $this->config->getDb()->fetchArray($res);
385
386
        // Don't ever login via anonymous user
387
        if (-1 === $user['user_id']) {
388
            return false;
389
        }
390
391
        $this->userId = (int)     $user['user_id'];
392
        $this->login   = (string) $user['login'];
393
        $this->status  = (string) $user['account_status'];
394
395
        // get user-data
396
        if (!$this->userdata instanceof PMF_User_UserData) {
397
            $this->userdata = new PMF_User_UserData($this->config);
398
        }
399
        $this->userdata->load($this->getUserId());
400
        return true;
401
    }
402
403
    /**
404
     * Checks if display name is already used. Returns true, if already in use
405
     *
406
     * @param string $name
407
     *
408
     * @return bool
409
     */
410 View Code Duplication
    public function checkDisplayName($name)
411
    {
412
        if (!$this->userdata instanceof PMF_User_UserData) {
413
            $this->userdata = new PMF_User_UserData($this->config);
414
        }
415
416
        if ($name === $this->userdata->fetch('display_name', $name)) {
417
            return true;
418
        } else {
419
            return false;
420
        }
421
    }
422
423
    /**
424
     * Checks if email address is already used. Returns true, if already in use
425
     *
426
     * @param string $name
427
     *
428
     * @return bool
429
     */
430 View Code Duplication
    public function checkMailAddress($name)
431
    {
432
        if (!$this->userdata instanceof PMF_User_UserData) {
433
            $this->userdata = new PMF_User_UserData($this->config);
434
        }
435
436
        if ($name === $this->userdata->fetch('email', $name)) {
437
            return true;
438
        } else {
439
            return false;
440
        }
441
    }
442
443
    /**
444
     * search users by login
445
     *
446
     * @param  string $search Login name
447
     * @return array
448
     */
449
    public function searchUsers($search)
450
    {
451
        $select = sprintf("
452
            SELECT
453
                login, 
454
                user_id,
455
                account_status
456
            FROM
457
                %sfaquser
458
            WHERE 
459
                login LIKE '%s'",
460
            PMF_Db::getTablePrefix(),
461
            $this->config->getDb()->escape($search.'%')
462
        );
463
464
        $res = $this->config->getDb()->query($select);
465
        if (!$res) {
466
            return array();
467
        }
468
469
        $result = array();
470
        while ($row = $this->config->getDb()->fetchArray($res)) {
471
            $result[] = $row;
472
        }
473
474
        return $result;
475
    }
476
477
    /**
478
     * creates a new user and stores basic data in the database.
479
     *
480
     * @param  string  $login  Login name
481
     * @param  string  $pass   Password
482
     * @param  integer $userId User ID
483
     * @return mixed
484
     */
485
    public function createUser($login, $pass = '', $userId = 0)
486
    {
487
        foreach ($this->authContainer as $auth) {
488
            if (!$this->checkAuth($auth)) {
489
                return false;
490
            }
491
        }
492
        
493
        // is $login valid?
494
        $login = (string)$login;
495
        if (!$this->isValidLogin($login)) {
496
            $this->errors[] = self::ERROR_USER_LOGINNAME_TOO_SHORT;
497
            return false;
498
        }
499
        
500
        // does $login already exist?
501
        if ($this->getUserByLogin($login, false)) {
502
            $this->errors[] = self::ERROR_USER_LOGIN_NOT_UNIQUE;
503
            return false;
504
        }
505
        
506
        // set user-ID
507
        if (0 == $userId) {
508
            $this->userId = (int) $this->config->getDb()->nextId(PMF_Db::getTablePrefix() . 'faquser', 'user_id');
509
        } else {
510
            $this->userId = $userId;
511
        }
512
        
513
        // create user entry
514
        $insert = sprintf("
515
            INSERT INTO
516
                %sfaquser
517
            (user_id, login, session_timestamp, member_since)
518
                VALUES
519
            (%d, '%s', %d, '%s')",
520
            PMF_Db::getTablePrefix(),
521
            $this->getUserId(),
522
            $this->config->getDb()->escape($login),
523
            $_SERVER['REQUEST_TIME'],
524
            date('YmdHis', $_SERVER['REQUEST_TIME'])
525
        );
526
527
        $this->config->getDb()->query($insert);
528
        if (!$this->userdata instanceof PMF_User_UserData) {
529
            $this->userdata = new PMF_User_UserData($this->config);
530
        }
531
        $data = $this->userdata->add($this->getUserId());
532
        if (!$data) {
533
            $this->errors[] = self::ERROR_USER_CANNOT_CREATE_USERDATA;
534
            return false;
535
        }
536
        
537
        // create authentication entry
538
        if ($pass == '') {
539
            $pass = $this->createPassword();
540
        }
541
        $success = false;
542
        foreach ($this->authContainer as $name => $auth) {
543
            if ($auth->setReadOnly()) {
544
                continue;
545
            }
546
            if (!$auth->add($login, $pass)) {
547
                $this->errors[] = self::ERROR_USER_CANNOT_CREATE_USER.'in Auth '.$name;
548
            } else {
549
                $success = true;
550
            }
551
        }
552
        if (!$success) {
553
            return false;
554
        }
555
556
        $this->perm->autoJoin($this->userId);
557
        return $this->getUserByLogin($login, false);
558
    }
559
560
    /**
561
     * deletes the user from the database.
562
     *
563
     * @return boolean
564
     */
565
    public function deleteUser()
566
    {
567
        if (!isset($this->userId) || $this->userId == 0) {
568
            $this->errors[] = self::ERROR_USER_NO_USERID;
569
            return false;
570
        }
571
        
572
        if (!isset($this->login) || strlen($this->login) == 0) {
573
            $this->errors[] = self::ERROR_USER_LOGIN_INVALID;
574
            return false;
575
        }
576
        
577
        if (isset($this->allowedStatus[$this->status]) && $this->allowedStatus[$this->status] == self::STATUS_USER_PROTECTED) {
578
            $this->errors[] = self::ERROR_USER_CANNOT_DELETE_USER . self::STATUS_USER_PROTECTED;
579
            return false;
580
        }
581
        
582
        $this->perm->refuseAllUserRights($this->userId);
583
        
584
        $delete = sprintf("
585
            DELETE FROM
586
                %sfaquser
587
            WHERE
588
                user_id = %d",
589
            PMF_Db::getTablePrefix(),
590
            $this->userId
591
        );
592
            
593
        $res = $this->config->getDb()->query($delete);
594 View Code Duplication
        if (!$res) {
595
            $this->errors[] = self::ERROR_USER_CANNOT_DELETE_USER . 'error(): ' . $this->config->getDb()->error();
596
            return false;
597
        }
598
        
599
        if (!$this->userdata instanceof PMF_User_UserData) {
600
            $this->userdata = new PMF_User_UserData($this->config);
601
        }
602
        $data = $this->userdata->delete($this->getUserId());
603
        if (!$data) {
604
            $this->errors[] = self::ERROR_USER_CANNOT_DELETE_USERDATA;
605
            return false;
606
        }
607
        
608
        $readOnly  = 0;
609
        $authCount = 0;
610
        $delete     = array();
611
        foreach ($this->authContainer as $auth) {
612
            $authCount++;
613
            if ($auth->setReadOnly()) {
614
                $readOnly++;
615
                continue;
616
            }
617
            $delete[] = $auth->delete($this->login);
618
        }
619
        
620
        if ($readOnly == $authCount) {
621
            $this->errors[] = self::ERROR_USER_NO_AUTH_WRITABLE;
622
        }
623
        if (!in_array(true, $delete)) {
624
            return false;
625
        }
626
        return true;
627
    }
628
629
    /**
630
     * changes the user's password. If $pass is omitted, a new
631
     * password is generated using the createPassword() method.
632
     *
633
     * @param  string $pass Password
634
     * @return boolean
635
     */
636
    public function changePassword($pass = '')
637
    {
638
        foreach ($this->authContainer as $auth) {
639
            if (!$this->checkAuth($auth)) {
640
                return false;
641
            }
642
        }
643
        
644
        $login = $this->getLogin();
645
        if ($pass == '') {
646
            $pass = $this->createPassword();
647
        }
648
        
649
        $success = false;
650
        foreach ($this->authContainer as $auth) {
651
            if ($auth->setReadOnly()) {
652
                continue;
653
            }
654
            if (!$auth->changePassword($login, $pass)) {
655
                continue;
656
            }
657
            else {
658
                $success = true;
659
            }
660
        }
661
        return $success;
662
    }
663
664
    /**
665
     * returns the user's status.
666
     *
667
     * @return string
668
     */
669
    public function getStatus()
670
    {
671
        if (isset($this->status) && strlen($this->status) > 0) {
672
            return $this->status;
673
        }
674
        return false;
675
    }
676
677
    /**
678
     * sets the user's status and updates the database entry.
679
     *
680
     * @param  string $status Status
681
     * @return boolean
682
     */
683
    public function setStatus($status)
684
    {
685
        // is status allowed?
686
        $status = strtolower($status);
687
        if (!in_array($status, array_keys($this->allowedStatus))) {
688
            $this->errors[] = self::ERROR_USER_INVALID_STATUS;
689
            return false;
690
        }
691
        
692
        // update status
693
        $this->status = $status;
694
        $update       = sprintf("
695
            UPDATE
696
                %sfaquser
697
            SET
698
                account_status = '%s'
699
            WHERE
700
                user_id = %d",
701
            PMF_Db::getTablePrefix(),
702
            $this->config->getDb()->escape($status),
703
            $this->userId
704
        );
705
        
706
        $res = $this->config->getDb()->query($update);
707
        
708
        if ($res) {
709
            return true;
710
        }
711
        return false;
712
    }
713
714
    /**
715
     * Returns a string with error messages.
716
     *
717
     * The string returned by error() contains messages for all errors that
718
     * during object procesing. Messages are separated by new lines.
719
     *
720
     * Error messages are stored in the public array errors.
721
     *
722
     * @return string
723
     */
724
    public function error()
725
    {
726
        $message = '';
727
        foreach ($this->errors as $error) {
728
            $message .= $error."\n";
729
        }
730
        $this->errors = array();
731
        return $message;
732
    }
733
734
    /**
735
     * returns true if login is a valid login string.
736
     *
737
     * $this->loginMinLength defines the minimum length the
738
     * login string. If login has more characters than allowed,
739
     * false is returned.
740
     * $this->login_invalidRegExp is a regular expression.
741
     * If login matches this false is returned.
742
     *
743
     * @param  string $login Login name
744
     * @return boolean
745
     */
746
    public function isValidLogin($login)
747
    {
748
        $login = (string) $login;
749
750
        if (strlen($login) < $this->loginMinLength || !preg_match($this->validUsername, $login)) {
751
            $this->errors[] = self::ERROR_USER_LOGIN_INVALID;
752
            return false;
753
        }
754
        return true;
755
    }
756
757
    /**
758
     * adds a new authentication object to the user object.
759
     *
760
     * @param  PMF_Auth $auth Auth object
761
     * @param  string   $name Auth name
762
     * @return boolean
763
     */
764
    public function addAuth($auth, $name)
765
    {
766
        if ($this->checkAuth($auth)) {
767
            $this->authContainer[$name] = $auth;
768
            return true;
769
        }
770
        return false;
771
    }
772
773
    /**
774
     * returns true if auth is a valid authentication object.
775
     *
776
     * @param  PMF_Auth $auth Auth object
777
     * @return bool
778
     */
779
    protected function checkAuth($auth)
780
    {
781
        $methods = array('checkPassword');
782
        foreach ($methods as $method) {
783
            if (!method_exists($auth, strtolower($method))) {
784
                $this->errors[] = self::ERROR_USER_NO_AUTH;
785
                return false;
786
                break;
787
            }
788
        }
789
        return true;
790
    }
791
792
    /**
793
     * Returns the data aof the auth container
794
     * @return array
795
     */
796
    public function getAuthContainer()
797
    {
798
        return $this->authContainer;
799
    }
800
801
    /**
802
     * Returns a specific entry from the auth data source array
803
     *
804
     * @param string $key
805
     *
806
     * @return string|null
807
     */
808
    public function getAuthSource($key)
809
    {
810
        if (isset($this->authData['authSource'][$key])) {
811
            return $this->authData['authSource'][$key];
812
        } else {
813
            return null;
814
        }
815
    }
816
817
    /**
818
     * Returns a specific entry from the auth data array
819
     *
820
     * @param string $key
821
     *
822
     * @return string|null
823
     */
824
    public function getAuthData($key)
825
    {
826
        if (isset($this->authData[$key])) {
827
            return $this->authData[$key];
828
        } else {
829
            return null;
830
        }
831
    }
832
833
    /**
834
     * returns true if perm is a valid permission object.
835
     *
836
     * @param  PMF_Perm $perm Perm object
837
     *
838
     * @return bool
839
     */
840
    private function checkPerm($perm)
841
    {
842
        if ($perm instanceof PMF_Perm) {
843
            return true;
844
        }
845
        $this->errors[] = self::ERROR_USER_NO_PERM;
846
        return false;
847
    }
848
849
    /**
850
     * returns the user's login.
851
     *
852
     * @return string
853
     */
854
    public function getLogin()
855
    {
856
        return $this->login;
857
    }
858
859
    /**
860
     * returns a new password.
861
     *
862
     * @return string
863
     */
864
    private function createPassword()
865
    {
866
        srand((double)microtime() * 1000000);
867
        return (string) uniqid(rand());
868
    }
869
870
    /**
871
     * Returns the data of the current user
872
     *
873
     * @param  string $field Field
874
     * @return array
875
     */
876
    public function getUserData($field = '*')
877
    {
878
        if (!($this->userdata instanceof PMF_User_UserData)) {
879
            $this->userdata = new PMF_User_UserData($this->config);
880
        }
881
        return $this->userdata->get($field);
882
    }
883
884
    /**
885
     * Adds user data
886
     *
887
     * @param  array $data Array with user data
888
     * @return bool
889
     */
890
    public function setUserData(Array $data)
891
    {
892
        if (!($this->userdata instanceof PMF_User_UserData)) {
893
            $this->userdata = new PMF_User_UserData($this->config);
894
        }
895
        $this->userdata->load($this->getUserId());
896
        return $this->userdata->set(array_keys($data), array_values($data));
897
    }
898
899
    /**
900
     * Returns an array with the user-IDs of all users found in
901
     * the database. By default, the Anonymous User will not be returned.
902
     *
903
     * @param boolean $withoutAnonymous  Without anonymous?
904
     * @param boolean $allowBlockedUsers Allow blocked users as well, e.g. in admin
905
     *
906
     * @return array
907
     */
908 View Code Duplication
    public function getAllUsers($withoutAnonymous = true, $allowBlockedUsers = true)
909
    {
910
        $select = sprintf("
911
            SELECT
912
                user_id
913
            FROM
914
                %sfaquser
915
            WHERE
916
                1 = 1
917
            %s
918
            %s
919
            ORDER BY
920
                user_id ASC",
921
            PMF_Db::getTablePrefix(),
922
            ($withoutAnonymous ? 'AND user_id <> -1' : ''),
923
            ($allowBlockedUsers ? '' : "AND account_status != 'blocked'")
924
        );
925
926
        $res = $this->config->getDb()->query($select);
927
        if (!$res) {
928
            return array();
929
        }
930
931
        $result = array();
932
        while ($row = $this->config->getDb()->fetchArray($res)) {
933
            $result[] = $row['user_id'];
934
        }
935
936
        return $result;
937
    }
938
939
    /**
940
     * Returns an array of all users found in the database. By default, the 
941
     * anonymous User will not be returned. The returned array contains the
942
     * user ID as key, the values are login name, account status, authentication
943
     * source and the user creation date.
944
     *
945
     * @param  boolean $withoutAnonymous Without anonymous?
946
     * @return array
947
     */
948 View Code Duplication
    public function getAllUserData($withoutAnonymous = true)
949
    {
950
        $select = sprintf("
951
            SELECT
952
                user_id, login, account_status, auth_source, member_since
953
            FROM
954
                %sfaquser
955
            %s
956
            ORDER BY
957
               login ASC",
958
            PMF_Db::getTablePrefix(),
959
            ($withoutAnonymous ? 'WHERE user_id <> -1' : ''));
960
961
        $res = $this->config->getDb()->query($select);
962
        if (!$res) {
963
            return array();
964
        }
965
966
        $result = array();
967
        while ($row = $this->config->getDb()->fetchArray($res)) {
968
            $result[$row['user_id']] = $row;
969
        }
970
971
        return $result;
972
    }
973
    
974
    /**
975
     * Get all users in <option> tags
976
     *
977
     * @param integer $id Selected user ID
978
     * @param boolean $allowBlockedUsers Allow blocked users as well, e.g. in admin
979
     *
980
     * @return string
981
     */
982
    public function getAllUserOptions($id = 1, $allowBlockedUsers = false)
983
    {
984
        $options  = '';
985
        $allUsers = $this->getAllUsers(true, $allowBlockedUsers);
986
987
        foreach ($allUsers as $userId) {
988
            if (-1 !== $userId) {
989
                $this->getUserById($userId);
990
                $options .= sprintf(
991
                    '<option value="%d"%s>%s (%s)</option>',
992
                    $userId,
993
                    (($userId === $id) ? ' selected' : ''),
994
                    $this->getUserData('display_name'),
995
                    $this->getLogin()
996
                );
997
            }
998
        }
999
        return $options;
1000
    }
1001
1002
    /**
1003
     * sets the minimum login string length
1004
     *
1005
     * @param  integer $loginMinLength Minimum length of login name
1006
     *
1007
     * @return void
1008
     */
1009
    public function setLoginMinLength($loginMinLength)
1010
    {
1011
        if (is_int($loginMinLength)) {
1012
            $this->loginMinLength = $loginMinLength;
1013
        }
1014
    }
1015
}
1016