1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Del\Service; |
4
|
|
|
|
5
|
|
|
use DateTime; |
6
|
|
|
use Del\Criteria\UserCriteria; |
7
|
|
|
use Del\Entity\EmailLink; |
8
|
|
|
use Del\Person\Entity\Person; |
9
|
|
|
use Del\Entity\User; |
10
|
|
|
use Del\Exception\EmailLinkException; |
11
|
|
|
use Del\Exception\UserException; |
12
|
|
|
use Del\Repository\UserRepository; |
13
|
|
|
use Del\Person\Service\PersonService; |
14
|
|
|
use Del\Value\User\State; |
15
|
|
|
use Doctrine\ORM\EntityManager; |
16
|
|
|
use InvalidArgumentException; |
17
|
|
|
use Pimple\Container; |
18
|
|
|
use Zend\Crypt\Password\Bcrypt; |
19
|
|
|
|
20
|
|
|
class UserService |
21
|
|
|
{ |
22
|
|
|
/** @var EntityManager $em */ |
23
|
|
|
protected $em; |
24
|
|
|
|
25
|
|
|
/** @var PersonService */ |
26
|
|
|
private $personSvc; |
27
|
|
|
|
28
|
22 |
|
public function __construct(Container $c) |
29
|
|
|
{ |
30
|
22 |
|
$this->em = $c['doctrine.entity_manager']; |
31
|
22 |
|
$this->personSvc = $c['service.person']; |
32
|
22 |
|
} |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @param array $data |
36
|
|
|
* @return User |
37
|
|
|
*/ |
38
|
16 |
|
public function createFromArray(array $data) |
39
|
|
|
{ |
40
|
16 |
|
$user = new User(); |
41
|
16 |
|
$person = isset($data['person']) ? $data['person'] : new Person(); |
42
|
16 |
|
$user->setPerson($person); |
43
|
16 |
|
isset($data['id']) ? $user->setId($data['id']) : null; |
44
|
16 |
|
isset($data['email']) ? $user->setEmail($data['email']) : null; |
45
|
16 |
|
isset($data['password']) ? $user->setPassword($data['password']) : null; |
46
|
16 |
|
isset($data['state']) ? $user->setState(new State($data['state'])) : null; |
47
|
16 |
|
isset($data['registrationDate']) ? $user->setRegistrationDate(new DateTime($data['registrationDate'])) : null; |
48
|
16 |
|
isset($data['lastLogin']) ? $user->setLastLogin(new DateTime($data['lastLogin'])) : null; |
49
|
16 |
|
return $user; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
|
53
|
|
|
|
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @return array |
57
|
|
|
*/ |
58
|
1 |
|
public function toArray(User $user) |
59
|
|
|
{ |
60
|
|
|
return array |
61
|
|
|
( |
62
|
1 |
|
'id' => $user->getID(), |
63
|
1 |
|
'email' => $user->getEmail(), |
64
|
1 |
|
'person' => $user->getPerson(), |
65
|
1 |
|
'password' => $user->getPassword(), |
66
|
1 |
|
'state' => $user->getState()->getValue(), |
67
|
1 |
|
'registrationDate' => is_null($user->getRegistrationDate()) ? null : $user->getRegistrationDate()->format('Y-m-d H:i:s'), |
68
|
1 |
|
'lastLoginDate' => is_null($user->getLastLoginDate()) ? null : $user->getLastLoginDate()->format('Y-m-d H:i:s'), |
69
|
1 |
|
); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @param User $user |
74
|
|
|
* @return User |
75
|
|
|
*/ |
76
|
16 |
|
public function saveUser(User $user) |
77
|
1 |
|
{ |
78
|
|
|
// $this->personSvc->savePerson($user->getPerson()); |
|
|
|
|
79
|
16 |
|
return $this->getUserRepository()->save($user); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @param int $id |
84
|
|
|
* @return User|null |
85
|
|
|
*/ |
86
|
1 |
View Code Duplication |
public function findUserById($id) |
|
|
|
|
87
|
|
|
{ |
88
|
1 |
|
$criteria = new UserCriteria(); |
89
|
1 |
|
$criteria->setId($id); |
90
|
1 |
|
$results = $this->getUserRepository()->findByCriteria($criteria); |
91
|
1 |
|
return (count($results)) ? $results[0] : null; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @param string $email |
96
|
|
|
* @return User|null |
97
|
|
|
*/ |
98
|
1 |
View Code Duplication |
public function findUserByEmail($email) |
|
|
|
|
99
|
|
|
{ |
100
|
1 |
|
$criteria = new UserCriteria(); |
101
|
1 |
|
$criteria->setEmail($email); |
102
|
1 |
|
$result = $this->getUserRepository()->findByCriteria($criteria); |
103
|
1 |
|
return count($result) ? $result[0] : null; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @return UserRepository |
108
|
|
|
*/ |
109
|
17 |
|
private function getUserRepository() |
110
|
|
|
{ |
111
|
17 |
|
return $this->em->getRepository('Del\Entity\User'); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* @return \Del\Repository\EmailLink |
116
|
|
|
*/ |
117
|
5 |
|
private function getEmailLinkRepository() |
118
|
|
|
{ |
119
|
5 |
|
return $this->em->getRepository('Del\Entity\EmailLink'); |
120
|
|
|
} |
121
|
|
|
|
122
|
4 |
|
public function registerUser(array $data) |
123
|
|
|
{ |
124
|
4 |
|
if (!isset($data['email']) || !isset($data['password']) || !isset($data['confirm'])) { |
125
|
1 |
|
throw new InvalidArgumentException(); |
126
|
|
|
} |
127
|
3 |
|
if ($data['password'] !== $data['confirm']) { |
128
|
1 |
|
throw new UserException(UserException::WRONG_PASSWORD); |
129
|
|
|
} |
130
|
|
|
|
131
|
2 |
|
$criteria = new UserCriteria(); |
132
|
2 |
|
$criteria->setEmail($data['email']); |
133
|
2 |
|
$user = $this->getUserRepository()->findByCriteria($criteria); |
134
|
2 |
|
if(!empty($user)) { |
135
|
1 |
|
throw new UserException(UserException::USER_EXISTS); |
136
|
|
|
} |
137
|
|
|
|
138
|
2 |
|
$person = new Person(); |
139
|
2 |
|
$user = new User(); |
140
|
2 |
|
$state = new State(State::STATE_UNACTIVATED); |
141
|
2 |
|
$user->setPerson($person) |
142
|
2 |
|
->setEmail($data['email']) |
143
|
2 |
|
->setRegistrationDate(new DateTime()) |
144
|
2 |
|
->setState($state); |
145
|
|
|
|
146
|
2 |
|
$bcrypt = new Bcrypt(); |
147
|
2 |
|
$bcrypt->setCost(14); |
148
|
|
|
|
149
|
2 |
|
$encryptedPassword = $bcrypt->create($data['password']); |
150
|
2 |
|
$user->setPassword($encryptedPassword); |
151
|
|
|
|
152
|
2 |
|
$this->saveUser($user); |
153
|
2 |
|
return $user; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @param User $user |
158
|
|
|
* @param $password |
159
|
|
|
* @return User |
160
|
|
|
*/ |
161
|
6 |
|
public function changePassword(User $user, $password) |
162
|
|
|
{ |
163
|
6 |
|
$bcrypt = new Bcrypt(); |
164
|
6 |
|
$bcrypt->setCost(14); |
165
|
|
|
|
166
|
6 |
|
$encryptedPassword = $bcrypt->create($password); |
167
|
6 |
|
$user->setPassword($encryptedPassword); |
168
|
|
|
|
169
|
6 |
|
$this->saveUser($user); |
170
|
6 |
|
return $user; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @param User $user |
175
|
|
|
* @param int $expiry_days |
176
|
|
|
* @return EmailLink |
177
|
|
|
*/ |
178
|
4 |
|
public function generateEmailLink(User $user, $expiry_days = 7) |
179
|
|
|
{ |
180
|
4 |
|
$date = new DateTime(); |
181
|
4 |
|
$date->modify('+'.$expiry_days.' days'); |
182
|
4 |
|
$token = md5(uniqid(rand(), true)); |
183
|
4 |
|
$link = new EmailLink(); |
184
|
4 |
|
$link->setUser($user); |
185
|
4 |
|
$link->setToken($token); |
186
|
4 |
|
$link->setExpiryDate($date); |
187
|
4 |
|
return $this->getEmailLinkRepository()->save($link); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @param EmailLink $link |
192
|
|
|
*/ |
193
|
4 |
|
public function deleteEmailLink(EmailLink $link) |
194
|
|
|
{ |
195
|
|
|
/** @var EmailLink $link */ |
196
|
4 |
|
$link = $this->em->merge($link); |
197
|
4 |
|
$this->getEmailLinkRepository()->delete($link); |
198
|
4 |
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* @param User $user |
202
|
|
|
*/ |
203
|
16 |
|
public function deleteUser(User $user, $deletePerson = false) |
204
|
|
|
{ |
205
|
16 |
|
$this->getUserRepository()->delete($user,$deletePerson); |
206
|
16 |
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* @param $email |
210
|
|
|
* @param $token |
211
|
|
|
* @return EmailLink |
212
|
|
|
* @throws EmailLinkException |
213
|
|
|
*/ |
214
|
4 |
|
public function findEmailLink($email, $token) |
215
|
|
|
{ |
216
|
4 |
|
$link = $this->getEmailLinkRepository()->findByToken($token); |
217
|
4 |
|
if(!$link) { |
218
|
1 |
|
throw new EmailLinkException(EmailLinkException::LINK_NOT_FOUND); |
219
|
|
|
} |
220
|
3 |
|
if($link->getUser()->getEmail() != $email) { |
221
|
1 |
|
throw new EmailLinkException(EmailLinkException::LINK_NO_MATCH); |
222
|
|
|
} |
223
|
2 |
|
if($link->getExpiryDate() < new DateTime()) { |
224
|
1 |
|
throw new EmailLinkException(EmailLinkException::LINK_EXPIRED); |
225
|
|
|
} |
226
|
1 |
|
return $link; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* @param string $email |
231
|
|
|
* @param string $password |
232
|
|
|
* @return int |
233
|
|
|
* @throws UserException |
234
|
|
|
*/ |
235
|
6 |
|
function authenticate($email, $password) |
|
|
|
|
236
|
|
|
{ |
237
|
6 |
|
$criteria = new UserCriteria(); |
238
|
6 |
|
$criteria->setEmail($email); |
239
|
|
|
|
240
|
6 |
|
$user = $this->getUserRepository()->findByCriteria($criteria); |
241
|
|
|
|
242
|
6 |
|
if(empty($user)) { |
243
|
1 |
|
throw new UserException(UserException::USER_NOT_FOUND); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** @var User $user */ |
247
|
5 |
|
$user = $user[0]; |
248
|
|
|
|
249
|
5 |
|
switch($user->getState()->getValue()) { |
250
|
5 |
|
case State::STATE_UNACTIVATED : |
|
|
|
|
251
|
1 |
|
throw new UserException(UserException::USER_UNACTIVATED); |
252
|
|
|
break; |
|
|
|
|
253
|
4 |
|
case State::STATE_DISABLED : |
|
|
|
|
254
|
4 |
|
case State::STATE_SUSPENDED : |
|
|
|
|
255
|
1 |
|
throw new UserException(UserException::USER_DISABLED); |
256
|
|
|
break; |
|
|
|
|
257
|
3 |
|
case State::STATE_BANNED : |
|
|
|
|
258
|
1 |
|
throw new UserException(UserException::USER_BANNED); |
259
|
|
|
break; |
|
|
|
|
260
|
|
|
|
261
|
2 |
|
} |
262
|
|
|
|
263
|
2 |
|
$bcrypt = new Bcrypt(); |
264
|
2 |
|
$bcrypt->setCost(14); |
265
|
|
|
|
266
|
2 |
|
if(!$bcrypt->verify($password, $user->getPassword())) |
267
|
2 |
|
{ |
268
|
1 |
|
throw new UserException(UserException::WRONG_PASSWORD); |
269
|
|
|
} |
270
|
|
|
|
271
|
1 |
|
return $user->getID(); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* @param UserCriteria $criteria |
276
|
|
|
* @return array |
277
|
|
|
*/ |
278
|
1 |
|
public function findByCriteria(UserCriteria $criteria) |
279
|
|
|
{ |
280
|
1 |
|
return $this->getUserRepository()->findByCriteria($criteria); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* @param User $user |
285
|
|
|
* @param $password |
286
|
|
|
* @return bool |
287
|
|
|
*/ |
288
|
1 |
|
public function checkPassword(User $user, $password) |
289
|
|
|
{ |
290
|
1 |
|
$bcrypt = new Bcrypt(); |
291
|
1 |
|
$bcrypt->setCost(14); |
292
|
|
|
|
293
|
1 |
|
return $bcrypt->verify($password, $user->getPassword()); |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
} |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.