Completed
Pull Request — master (#297)
by Anton
10:47 queued 09:01
created

Row::getPrivileges()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 9.4285
ccs 4
cts 4
cp 1
crap 2
1
<?php
2
/**
3
 * @copyright Bluz PHP Team
4
 * @link      https://github.com/bluzphp/skeleton
5
 */
6
7
declare(strict_types=1);
8
9
namespace Application\Users;
10
11
use Application\Exception;
12
use Application\Privileges;
13
use Application\Roles;
14
use Bluz\Auth\AbstractRowEntity;
15
use Bluz\Auth\AuthException;
16
use Bluz\Proxy\Auth;
17
use Bluz\Proxy\Session;
18
use Bluz\Validator\Traits\Validator;
19
20
/**
21
 * User
22
 *
23
 * @package  Application\Users
24
 *
25
 * @property integer $id
26
 * @property string  $login
27
 * @property string  $email
28
 * @property string  $created
29
 * @property string  $updated
30
 * @property string  $status
31
 *
32
 * @SWG\Definition(definition="users", title="user", required={"id", "login", "status"})
33
 * @SWG\Property(property="id", type="integer", description="User UID", example=2)
34
 * @SWG\Property(property="login", type="string", description="Login", example="admin")
35
 * @SWG\Property(property="email", type="string", description="Email", example="[email protected]")
36
 * @SWG\Property(property="created", type="string", format="date-time", example="2017-01-01 20:17:01")
37
 * @SWG\Property(property="updated", type="string", format="date-time", example="2017-01-01 20:17:01")
38
 * @SWG\Property(property="status", type="string", enum={"pending", "active", "disabled", "deleted"})
39
 */
40
class Row extends AbstractRowEntity
41
{
42
    use Validator;
43
44
    /**
45
     * Small cache of user privileges
46
     *
47
     * @var array
48
     */
49
    protected $privileges;
50
51
    /**
52
     * @return void
53
     */
54
    public function beforeSave()
55
    {
56
        $this->email = strtolower($this->email ?? '');
57
58
        $this->addValidator('login')
59
            ->required()
60
            ->latin()
61
            ->length(3, 255)
62
            ->callback(
63
                function ($login) {
64
                    $selector = static::getTable()
65
                        ::select()
66
                        ->where('login = ?', $login);
67
68
                    if ($this->id) {
69
                        $selector->andWhere('id != ?', $this->id);
70
                    }
71
72
                    $user = $selector->execute();
73
                    return !$user;
74
                },
75
                'User with this login is already exists'
76
            );
77
78
        $this->addValidator('email')
79
            ->required()
80
            ->email(true)
81
            ->callback(
82
                function ($email) {
83
                    $selector = static::getTable()
84
                        ::select()
85
                        ->where('email = ?', $email);
86
87
                    if ($this->id) {
88
                        $selector->andWhere('id != ?', $this->id);
89
                    }
90
91
                    $user = $selector->execute();
92
                    return !$user;
93
                },
94
                'User with this email is already exists'
95
            );
96
    }
97
98
    /**
99
     * @return void
100
     */
101
    public function beforeInsert()
102
    {
103
        $this->created = gmdate('Y-m-d H:i:s');
104
    }
105
106
    /**
107
     * @return void
108
     */
109
    public function beforeUpdate()
110
    {
111
        $this->updated = gmdate('Y-m-d H:i:s');
112
    }
113
114
    /**
115
     * Can entity login
116
     *
117
     * @throws Exception
118
     * @throws AuthException
119
     * @return void
120
     */
121
    public function tryLogin()
122
    {
123
        switch ($this->status) {
124
            case (Table::STATUS_PENDING):
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
125
                throw new AuthException('Your account is pending activation', 403);
126
            case (Table::STATUS_DISABLED):
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
127
                throw new AuthException('Your account is disabled by administrator', 403);
128
            case (Table::STATUS_ACTIVE):
129
                // all ok
130
                // regenerate session
131
                if (PHP_SAPI !== 'cli') {
132
                    Session::regenerateId();
133
                }
134
                // save user to new session
135
                Auth::setIdentity($this);
136
                break;
137
            default:
138
                throw new Exception('User status is undefined in system');
139
        }
140
    }
141
142
    /**
143
     * Get user roles
144
     */
145
    public function getRoles()
146
    {
147
        return Roles\Table::getInstance()->getUserRoles($this->id);
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153 6
    public function getPrivileges(): array
154
    {
155 6
        if (!$this->privileges) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->privileges of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
156 6
            $this->privileges = Privileges\Table::getInstance()->getUserPrivileges($this->id);
157
        }
158 6
        return $this->privileges;
159
    }
160
161
    /**
162
     * Check user role
163
     *
164
     * @param integer $roleId
165
     *
166
     * @return boolean
167
     */
168 1
    public function hasRole($roleId)
169
    {
170 1
        $roles = Roles\Table::getInstance()->getUserRolesIdentity($this->id);
171
172 1
        return in_array($roleId, $roles);
173
    }
174
}
175