1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Admin\Service; |
6
|
|
|
|
7
|
|
|
use Admin\Filter\AdminUserFilter; |
8
|
|
|
use Admin\Mapper\AdminUsersMapper; |
9
|
|
|
use MysqlUuid\Formats\Binary; |
10
|
|
|
use MysqlUuid\Uuid as MysqlUuid; |
11
|
|
|
use Ramsey\Uuid\Uuid; |
12
|
|
|
use Std\FilterException; |
13
|
|
|
use UploadHelper\Upload; |
14
|
|
|
use Zend\Crypt\Password\Bcrypt; |
15
|
|
|
use Zend\Paginator\Adapter\DbSelect; |
16
|
|
|
use Zend\Paginator\Paginator; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class AdminUserService. |
20
|
|
|
*/ |
21
|
|
|
class AdminUserService |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var Bcrypt |
25
|
|
|
*/ |
26
|
|
|
private $crypt; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var AdminUsersMapper |
30
|
|
|
*/ |
31
|
|
|
private $adminUsersMapper; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var AdminUserFilter |
35
|
|
|
*/ |
36
|
|
|
private $adminUserFilter; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var Upload |
40
|
|
|
*/ |
41
|
|
|
private $upload; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* AdminUserService constructor. |
45
|
|
|
* |
46
|
|
|
* @param Bcrypt $crypt bcrypt password encryption method |
47
|
|
|
* @param AdminUsersMapper $adminUsersMapper mapper for admin us |
48
|
|
|
* @param AdminUserFilter $adminUserFilter |
49
|
|
|
* @param Upload $upload |
50
|
|
|
*/ |
51
|
|
|
public function __construct( |
52
|
|
|
Bcrypt $crypt, |
53
|
|
|
AdminUsersMapper $adminUsersMapper, |
54
|
|
|
AdminUserFilter $adminUserFilter, |
55
|
|
|
Upload $upload |
56
|
|
|
) { |
57
|
|
|
$this->crypt = $crypt; |
58
|
|
|
$this->adminUsersMapper = $adminUsersMapper; |
59
|
|
|
$this->adminUserFilter = $adminUserFilter; |
60
|
|
|
$this->upload = $upload; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Performs user login or throws exception if credentials are not valid. |
65
|
|
|
* |
66
|
|
|
* @param string $email user email |
67
|
|
|
* @param string $password user password |
68
|
|
|
* |
69
|
|
|
* @throws \Exception if user does not exist or password is not valid |
70
|
|
|
* |
71
|
|
|
* @return array|\ArrayObject|null |
72
|
|
|
*/ |
73
|
|
|
public function loginUser($email, $password) |
74
|
|
|
{ |
75
|
|
|
if (!$email || !$password) { |
76
|
|
|
throw new \Exception('Both email and password are required.', 400); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
$user = $this->adminUsersMapper->getByEmail($email); |
80
|
|
|
|
81
|
|
|
if (!$user) { |
82
|
|
|
throw new \Exception('User does not exist.'); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
if (!$this->crypt->verify($password, $user->password)) { |
86
|
|
|
throw new \Exception('Password does not match.'); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
$this->adminUsersMapper->updateLogin($user->admin_user_id); |
90
|
|
|
|
91
|
|
|
return $user; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Return pagination object to paginate results on view. |
96
|
|
|
* |
97
|
|
|
* @param int $page Current page set to pagination to display |
98
|
|
|
* @param int $limit Limit set to pagination |
99
|
|
|
* @param string $userId UUID from DB |
100
|
|
|
* |
101
|
|
|
* @return Paginator |
102
|
|
|
*/ |
103
|
|
View Code Duplication |
public function getPagination($page, $limit, $userId) |
|
|
|
|
104
|
|
|
{ |
105
|
|
|
$select = $this->adminUsersMapper->getPaginationSelect($userId); |
106
|
|
|
$paginationAdapter = new DbSelect($select, $this->adminUsersMapper->getAdapter()); |
|
|
|
|
107
|
|
|
$pagination = new Paginator($paginationAdapter); |
108
|
|
|
|
109
|
|
|
$pagination->setCurrentPageNumber($page); |
110
|
|
|
$pagination->setItemCountPerPage($limit); |
111
|
|
|
|
112
|
|
|
return $pagination; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Return one user for given UUID. |
117
|
|
|
* |
118
|
|
|
* @param string $userId UUID from DB |
119
|
|
|
* |
120
|
|
|
* @return array|\ArrayObject|null |
121
|
|
|
*/ |
122
|
|
|
public function getUser($userId) |
123
|
|
|
{ |
124
|
|
|
return $this->adminUsersMapper->get($userId); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
public function registerNewUser($data) |
128
|
|
|
{ |
129
|
|
|
$filter = $this->adminUserFilter->getInputFilter()->setData($data); |
130
|
|
|
|
131
|
|
|
if (!$filter->isValid()) { |
132
|
|
|
throw new FilterException($filter->getMessages()); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
$data = $filter->getValues() + [ |
136
|
|
|
'face_img' => $this->upload->uploadImage($data, 'face_img'), |
137
|
|
|
'profile_img' => $this->upload->uploadImage($data, 'profile_img'), |
138
|
|
|
]; |
139
|
|
|
|
140
|
|
|
unset($data['confirm_password']); |
141
|
|
|
$data['password'] = $this->crypt->create($data['password']); |
142
|
|
|
$data['admin_user_id'] = Uuid::uuid1()->toString(); |
143
|
|
|
$data['admin_user_uuid'] = (new MysqlUuid($data['admin_user_id']))->toFormat(new Binary()); |
144
|
|
|
|
145
|
|
|
return $this->adminUsersMapper->insert($data); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Refactor it. |
150
|
|
|
*/ |
151
|
|
|
public function updateUser($data, $userId) |
152
|
|
|
{ |
153
|
|
|
$user = $this->getUser($userId); |
154
|
|
|
$filter = $this->adminUserFilter->getInputFilter()->setData($data); |
155
|
|
|
|
156
|
|
|
// we dont want to force user to enter the password again |
157
|
|
|
if ($data['password'] == '') { |
158
|
|
|
$filter->remove('password'); |
159
|
|
|
$filter->remove('confirm_password'); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
// if we want to keep same email |
163
|
|
|
if ($user->email == $data['email']) { |
164
|
|
|
$filter->remove('email'); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
if (!$filter->isValid()) { |
168
|
|
|
throw new FilterException($filter->getMessages()); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
$data = $filter->getValues() + [ |
172
|
|
|
'face_img' => $this->upload->uploadImage($data, 'face_img'), |
173
|
|
|
'profile_img' => $this->upload->uploadImage($data, 'profile_img'), |
174
|
|
|
]; |
175
|
|
|
|
176
|
|
|
// We don't want to force user to re-upload image on edit |
177
|
|
|
if (!$data['face_img']) { |
178
|
|
|
unset($data['face_img']); |
179
|
|
|
} else { |
180
|
|
|
$this->upload->deleteFile($user->face_img); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
if (!$data['profile_img']) { |
184
|
|
|
unset($data['profile_img']); |
185
|
|
|
} else { |
186
|
|
|
$this->upload->deleteFile($user->profile_img); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
if (isset($data['password'])) { |
190
|
|
|
unset($data['confirm_password']); |
191
|
|
|
$data['password'] = $this->crypt->create($data['password']); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
return $this->adminUsersMapper->update($data, ['admin_user_id' => $userId]); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Delete user by given UUID. |
199
|
|
|
* |
200
|
|
|
* @param $userId |
201
|
|
|
* |
202
|
|
|
* @throws \Exception |
203
|
|
|
* |
204
|
|
|
* @return bool |
205
|
|
|
*/ |
206
|
|
|
public function delete($userId) |
207
|
|
|
{ |
208
|
|
|
if (!($adminUser = $this->getUser($userId))) { |
209
|
|
|
throw new \Exception('Admin user not found.'); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
$this->upload->deleteFile($adminUser->face_img); |
213
|
|
|
$this->upload->deleteFile($adminUser->profile_img); |
214
|
|
|
|
215
|
|
|
return (bool) $this->adminUsersMapper->delete(['admin_user_id' => $userId]); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* Fetch random X users to show on homepage. |
220
|
|
|
* |
221
|
|
|
* @param int $limit |
222
|
|
|
* |
223
|
|
|
* @return null|\Zend\Db\ResultSet\ResultSetInterface |
224
|
|
|
*/ |
225
|
|
|
public function getForWeb($limit = 10) |
226
|
|
|
{ |
227
|
|
|
return $this->adminUsersMapper->getRandom($limit); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Return all Admin User for select box. |
232
|
|
|
* |
233
|
|
|
* @return \Zend\Db\ResultSet\ResultSet |
234
|
|
|
*/ |
235
|
|
|
public function getAll() |
236
|
|
|
{ |
237
|
|
|
return $this->adminUsersMapper->select(); |
238
|
|
|
} |
239
|
|
|
} |
240
|
|
|
|
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.