Completed
Push — master ( 028b40...025e52 )
by Gabriel
08:34
created

getEmailConfirmationTokenAttempts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Sinergi\Users\User;
4
5
use DateTime;
6
use Sinergi\Users\Group\GroupEntityInterface;
7
use Sinergi\Users\Group\GroupRepositoryInterface;
8
use Sinergi\Users\Session\SessionEntityInterface;
9
use Sinergi\Users\Session\SessionRepositoryInterface;
10
use Sinergi\Users\Utils\Token;
11
use DateInterval;
12
13
trait UserEntityTrait
14
{
15
    protected $id;
16
    protected $groupId;
17
    /** @var GroupEntityInterface */
18
    protected $group;
19
    /** @var SessionEntityInterface[] */
20
    protected $sessions;
21
    protected $status;
22
    protected $isAdmin;
23
    protected $email = null;
24
    protected $pendingEmail = null;
25
    protected $deletedEmail = null;
26
    protected $isEmailConfirmed = false;
27
    protected $emailConfirmationToken;
28
    protected $emailConfirmationTokenAttempts;
29
    protected $emailConfirmationTokenExpirationDatetime;
30
    protected $lastEmailTokenGeneratedDatetime;
31
    protected $password;
32
    protected $passwordResetToken;
33
    protected $passwordResetTokenExpirationDatetime;
34
    protected $lastPasswordResetTokenGeneratedDatetime;
35
    protected $creationDatetime;
36
    protected $modificationDatetime;
37
    /** @var GroupRepositoryInterface */
38
    protected $groupRepository;
39
    /** @var SessionRepositoryInterface */
40
    protected $sessionRepository;
41
42
    public function __construct(
43
        GroupRepositoryInterface $groupRepository = null,
44
        SessionRepositoryInterface $sessionRepository = null
45
    ) {
46
        $this->groupRepository = $groupRepository;
47
        $this->sessionRepository = $sessionRepository;
48
        $this->setStatus(UserEntityInterface::STATUS_ACTIVE);
49
        $this->setCreationDatetime(new DateTime());
50
        $this->setModificationDatetime(new DateTime());
51
    }
52
53
    /** @return int */
54
    public function getId()
55
    {
56
        return $this->id;
57
    }
58
59
    public function setId(int $id): UserEntityInterface
60
    {
61
        $this->id = $id;
62
        return $this;
63
    }
64
65
    /** @return int|null */
66
    public function getGroupId()
67
    {
68
        return $this->groupId;
69
    }
70
71
    public function setGroupId(int $groupId = null): UserEntityInterface
72
    {
73
        $this->groupId = $groupId;
74
        return $this;
75
    }
76
77
    /** @return GroupEntityInterface|null */
78
    public function getGroup()
79
    {
80
        if ($this->group && $this->group->getId() === $this->groupId) {
81
            return $this->group;
82
        } elseif (!$this->groupRepository) {
83
            throw new \Exception('Cannot fetch group without group repository');
84
        }
85
        return $this->group = $this->groupRepository->findById($this->getGroupId());
86
    }
87
88
    public function setGroup(GroupEntityInterface $group = null): UserEntityInterface
89
    {
90
        $this->setGroupId($group->getId());
0 ignored issues
show
Bug introduced by
It seems like $group is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
91
        $this->group = $group;
92
        return $this;
93
    }
94
95
    /** @return SessionEntityInterface[] */
96
    public function getSessions()
97
    {
98
        if (is_array($this->sessions)) {
99
            return $this->sessions;
100
        } elseif (!$this->sessionRepository) {
101
            throw new \Exception('Cannot fetch sessions without session repository');
102
        }
103
        return $this->sessions = $this->sessionRepository->findByUserId($this->getId());
104
    }
105
106
    /** @return string|null */
107
    public function getStatus()
108
    {
109
        return $this->status;
110
    }
111
112
    public function setStatus(string $status): UserEntityInterface
113
    {
114
        $this->status = $status;
115
        return $this;
116
    }
117
118
    public function isAdmin(): bool
119
    {
120
        return $this->isAdmin;
121
    }
122
123
    public function setIsAdmin(bool $isAdmin): UserEntityInterface
124
    {
125
        $this->isAdmin = $isAdmin;
126
        return $this;
127
    }
128
129
    public function isActive(): bool
130
    {
131
        return $this->getStatus() === UserEntityInterface::STATUS_ACTIVE;
132
    }
133
134
    public function getEmail(): string
135
    {
136
        return $this->email ?: '';
137
    }
138
139
    public function setEmail(string $email): UserEntityInterface
140
    {
141
        $this->email = $email;
142
        return $this;
143
    }
144
145
    /** @return string */
146
    public function getPendingEmail()
147
    {
148
        return $this->pendingEmail;
149
    }
150
151
    public function setPendingEmail(string $pendingEmail): UserEntityInterface
152
    {
153
        $this->pendingEmail = $pendingEmail;
154
        return $this;
155
    }
156
157
    public function isEmailConfirmed(): bool
158
    {
159
        return $this->isEmailConfirmed;
160
    }
161
162
    public function setIsEmailConfirmed(bool $isEmailConfirmed): UserEntityInterface
163
    {
164
        $this->isEmailConfirmed = $isEmailConfirmed;
165
        return $this;
166
    }
167
168
    /** @return string */
169
    public function getEmailConfirmationToken()
170
    {
171
        return $this->emailConfirmationToken;
172
    }
173
174
    public function setEmailConfirmationToken(string $emailConfirmationToken = null): UserEntityInterface
175
    {
176
        $this->emailConfirmationToken = $emailConfirmationToken;
177
        return $this;
178
    }
179
180
    /** @return int */
181
    public function getEmailConfirmationTokenAttempts()
182
    {
183
        return $this->emailConfirmationTokenAttempts;
184
    }
185
186
    public function setEmailConfirmationTokenAttempts(int $emailConfirmationTokenAttempts = 0): UserEntityInterface
187
    {
188
        $this->emailConfirmationTokenAttempts = $emailConfirmationTokenAttempts;
189
        return $this;
190
    }
191
192
    /** @return DateTime */
193
    public function getEmailConfirmationTokenExpirationDatetime()
194
    {
195
        return $this->emailConfirmationTokenExpirationDatetime;
196
    }
197
198
    public function setEmailConfirmationTokenExpirationDatetime(
199
        DateTime $emailConfirmationTokenExpirationDatetime = null
200
    ): UserEntityInterface {
201
        $this->emailConfirmationTokenExpirationDatetime = $emailConfirmationTokenExpirationDatetime;
202
        return $this;
203
    }
204
205
    /** @return DateTime */
206
    public function getLastEmailTokenGeneratedDatetime()
207
    {
208
        return $this->lastEmailTokenGeneratedDatetime;
209
    }
210
211
    public function setLastEmailTokenGeneratedDatetime(
212
        DateTime $lastEmailTokenGeneratedDatetime
213
    ): UserEntityInterface {
214
        $this->lastEmailTokenGeneratedDatetime = $lastEmailTokenGeneratedDatetime;
215
        return $this;
216
    }
217
218
    public function hasEmailConfirmationTokenCooldownExpired(): bool
219
    {
220
        return (new DateTime())->getTimestamp() - $this->getLastEmailTokenGeneratedDatetime()->getTimestamp() >
221
            UserEntityInterface::EMAIL_COOLDOWN;
222
    }
223
224
    public function hasEmailConfirmationTokenExpired(): bool
225
    {
226
        return ($this->getEmailConfirmationTokenExpirationDatetime() <= new DateTime());
227
    }
228
229
    public function hasTooManyEmailConfirmationTokenAttempts(): bool
230
    {
231
        return $this->getEmailConfirmationTokenAttempts() > 5;
232
    }
233
234
    public function generateEmailConfirmationToken($token = null, DateInterval $expiration = null): UserEntityInterface
235
    {
236
        if (null === $expiration) {
237
            $expiration = new DateInterval('P1D');
238
        }
239
        $this->setEmailConfirmationTokenAttempts(0);
240
        $this->setEmailConfirmationToken(null === $token ? Token::generate(40) : $token);
241
        $this->setEmailConfirmationTokenExpirationDatetime((new DateTime())->add($expiration));
242
        $this->setLastEmailTokenGeneratedDatetime(new DateTime());
243
        return $this;
244
    }
245
246
    /** @return string */
247
    public function getDeletedEmail()
248
    {
249
        return $this->deletedEmail;
250
    }
251
252
    public function setDeletedEmail(string $deletedEmail): UserEntityInterface
253
    {
254
        $this->deletedEmail = $deletedEmail;
255
        return $this;
256
    }
257
258
    /** @return string */
259
    public function getPassword()
260
    {
261
        return $this->password;
262
    }
263
264
    public function setPassword(string $password): UserEntityInterface
265
    {
266
        $this->password = $password;
267
        $this->hashPassword();
268
        return $this;
269
    }
270
271
    /** @return string */
272
    public function getPasswordResetToken()
273
    {
274
        return $this->passwordResetToken;
275
    }
276
277
    public function setPasswordResetToken(string $passwordResetToken): UserEntityInterface
278
    {
279
        $this->passwordResetToken = $passwordResetToken;
280
        return $this;
281
    }
282
283
    /** @return DateTime */
284
    public function getPasswordResetTokenExpirationDatetime()
285
    {
286
        return $this->passwordResetTokenExpirationDatetime;
287
    }
288
289
    public function setPasswordResetTokenExpirationDatetime(
290
        DateTime $passwordResetTokenExpirationDatetime
291
    ): UserEntityInterface {
292
        $this->passwordResetTokenExpirationDatetime = $passwordResetTokenExpirationDatetime;
293
        return $this;
294
    }
295
296
    /** @return DateTime */
297
    public function getLastPasswordResetTokenGeneratedDatetime()
298
    {
299
        return $this->lastPasswordResetTokenGeneratedDatetime;
300
    }
301
302
    public function setLastPasswordResetTokenGeneratedDatetime(
303
        DateTime $lastPasswordResetTokenGeneratedDatetime
304
    ): UserEntityInterface {
305
        $this->lastPasswordResetTokenGeneratedDatetime = $lastPasswordResetTokenGeneratedDatetime;
306
        return $this;
307
    }
308
309
    public function canGenerateNewResetPasswordToken(): bool
310
    {
311
        $lastGenerated = $this->getLastPasswordResetTokenGeneratedDatetime();
312
        return (
313
            empty($lastGenerated) ||
314
            (new DateTime())->getTimestamp() - $lastGenerated->getTimestamp() > UserEntityInterface::EMAIL_COOLDOWN
315
        );
316
    }
317
318
    public function generatePasswordResetToken(): UserEntityInterface
319
    {
320
        if ($this->canGenerateNewResetPasswordToken()) {
321
            $this->setPasswordResetToken(Token::generate(40));
322
            $this->setLastPasswordResetTokenGeneratedDatetime(new DateTime());
323
        }
324
        return $this;
325
    }
326
327
    protected function hashPassword(): UserEntityInterface
328
    {
329
        $this->password = password_hash(
330
            (string) $this->password,
331
            PASSWORD_DEFAULT
332
        );
333
        return $this;
334
    }
335
336
    public function testPassword(string $password): bool
337
    {
338
        return password_verify($password, $this->password);
339
    }
340
341
    public function getCreationDatetime(): DateTime
342
    {
343
        return $this->creationDatetime;
344
    }
345
346
    public function setCreationDatetime(DateTime $creationDatetime): UserEntityInterface
347
    {
348
        $this->creationDatetime = $creationDatetime;
349
        return $this;
350
    }
351
352
    public function getModificationDatetime(): DateTime
353
    {
354
        return $this->modificationDatetime;
355
    }
356
357
    public function setModificationDatetime(DateTime $modificationDatetime): UserEntityInterface
358
    {
359
        $this->modificationDatetime = $modificationDatetime;
360
        return $this;
361
    }
362
363
    public function setGroupRepository(GroupRepositoryInterface $groupRepository): UserEntityInterface
364
    {
365
        $this->groupRepository = $groupRepository;
366
        return $this;
367
    }
368
369
    public function setSessionRepository(SessionRepositoryInterface $sessionRepository): UserEntityInterface
370
    {
371
        $this->sessionRepository = $sessionRepository;
372
        return $this;
373
    }
374
375
    public function toArray(): array
376
    {
377
        return [
378
            'id' => $this->getId(),
379
            'groupId' => $this->getGroupId(),
380
            'status' => $this->getStatus(),
381
            'isAdmin' => $this->isAdmin(),
382
            'email' => $this->getEmail(),
383
            'pendingEmail' => $this->getPendingEmail(),
384
            'deletedEmail' => $this->getDeletedEmail(),
385
            'isEmailConfirmed' => $this->isEmailConfirmed(),
386
            'emailConfirmationToken' => $this->getEmailConfirmationToken(),
387
            'emailConfirmationTokenExpirationDatetime' => $this->getEmailConfirmationTokenExpirationDatetime() ?
388
                $this->getEmailConfirmationTokenExpirationDatetime()->format('Y-m-d H:i:s') : null,
389
            'lastEmailTokenGeneratedDatetime' => $this->getLastEmailTokenGeneratedDatetime() ?
390
                $this->getLastEmailTokenGeneratedDatetime()->format('Y-m-d H:i:s') : null,
391
            'password' => $this->getPassword(),
392
            'passwordResetToken' => $this->getPasswordResetToken(),
393
            'passwordResetTokenExpirationDatetime' => $this->getPasswordResetTokenExpirationDatetime() ?
394
                $this->getPasswordResetTokenExpirationDatetime()->format('Y-m-d H:i:s') : null,
395
            'lastPasswordResetTokenGeneratedDatetime' => $this->getLastPasswordResetTokenGeneratedDatetime() ?
396
                $this->getLastPasswordResetTokenGeneratedDatetime()->format('Y-m-d H:i:s') : null,
397
            'creationDatetime' => $this->getCreationDatetime()->format('Y-m-d H:i:s'),
398
            'modificationDatetime' => $this->getModificationDatetime()->format('Y-m-d H:i:s'),
399
        ];
400
    }
401
402
    public function jsonSerialize()
403
    {
404
        return array_intersect_key(
405
            $this->toArray(),
406
            [
407
                'id' => null,
408
                'groupId' => null,
409
                'status' => null,
410
                'isAdmin' => null,
411
                'email' => null,
412
                'isEmailConfirmed' => null,
413
                'creationDatetime' => null,
414
                'modificationDatetime' => null,
415
            ]
416
        );
417
    }
418
}
419