|
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): |
|
|
|
|
|
|
125
|
|
|
throw new AuthException('Your account is pending activation', 403); |
|
126
|
|
|
case (Table::STATUS_DISABLED): |
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
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
|
|
|
|
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.
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.