Completed
Push — master ( a5d24e...028b40 )
by Gabriel
02:43
created

UserEntityTrait   C

Complexity

Total Complexity 63

Size/Duplication

Total Lines 383
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 63
c 0
b 0
f 0
lcom 1
cbo 1
dl 0
loc 383
rs 5.8893

49 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A getId() 0 4 1
A setId() 0 5 1
A getGroupId() 0 4 1
A setGroupId() 0 5 1
A getGroup() 0 9 4
A setGroup() 0 6 1
A getSessions() 0 9 3
A getStatus() 0 4 1
A setStatus() 0 5 1
A isAdmin() 0 4 1
A setIsAdmin() 0 5 1
A isActive() 0 4 1
A getEmail() 0 4 2
A setEmail() 0 5 1
A getPendingEmail() 0 4 1
A setPendingEmail() 0 5 1
A isEmailConfirmed() 0 4 1
A setIsEmailConfirmed() 0 5 1
A getEmailConfirmationToken() 0 4 1
A setEmailConfirmationToken() 0 5 1
A getEmailConfirmationTokenExpirationDatetime() 0 4 1
A setEmailConfirmationTokenExpirationDatetime() 0 6 1
A getLastEmailTokenGeneratedDatetime() 0 4 1
A setLastEmailTokenGeneratedDatetime() 0 6 1
A canGenerateNewEmailConfirmationToken() 0 8 2
A generateEmailConfirmationToken() 0 8 2
A getDeletedEmail() 0 4 1
A setDeletedEmail() 0 5 1
A getPassword() 0 4 1
A setPassword() 0 6 1
A getPasswordResetToken() 0 4 1
A setPasswordResetToken() 0 5 1
A getPasswordResetTokenExpirationDatetime() 0 4 1
A setPasswordResetTokenExpirationDatetime() 0 6 1
A getLastPasswordResetTokenGeneratedDatetime() 0 4 1
A setLastPasswordResetTokenGeneratedDatetime() 0 6 1
A canGenerateNewResetPasswordToken() 0 8 2
A generatePasswordResetToken() 0 8 2
A hashPassword() 0 8 1
A testPassword() 0 4 1
A getCreationDatetime() 0 4 1
A setCreationDatetime() 0 5 1
A getModificationDatetime() 0 4 1
A setModificationDatetime() 0 5 1
A setGroupRepository() 0 5 1
A setSessionRepository() 0 5 1
B toArray() 0 26 5
A jsonSerialize() 0 16 1

How to fix   Complexity   

Complex Class

Complex classes like UserEntityTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UserEntityTrait, and based on these observations, apply Extract Interface, too.

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
12
trait UserEntityTrait
13
{
14
    protected $id;
15
    protected $groupId;
16
    /** @var GroupEntityInterface */
17
    protected $group;
18
    /** @var SessionEntityInterface[] */
19
    protected $sessions;
20
    protected $status;
21
    protected $isAdmin;
22
    protected $email = null;
23
    protected $pendingEmail = null;
24
    protected $deletedEmail = null;
25
    protected $isEmailConfirmed = false;
26
    protected $emailConfirmationToken;
27
    protected $emailConfirmationTokenExpirationDatetime;
28
    protected $lastEmailTokenGeneratedDatetime;
29
    protected $password;
30
    protected $passwordResetToken;
31
    protected $passwordResetTokenExpirationDatetime;
32
    protected $lastPasswordResetTokenGeneratedDatetime;
33
    protected $creationDatetime;
34
    protected $modificationDatetime;
35
    /** @var GroupRepositoryInterface */
36
    protected $groupRepository;
37
    /** @var SessionRepositoryInterface */
38
    protected $sessionRepository;
39
40
    public function __construct(
41
        GroupRepositoryInterface $groupRepository = null,
42
        SessionRepositoryInterface $sessionRepository = null
43
    ) {
44
        $this->groupRepository = $groupRepository;
45
        $this->sessionRepository = $sessionRepository;
46
        $this->setStatus(UserEntityInterface::STATUS_ACTIVE);
47
        $this->setCreationDatetime(new DateTime());
48
        $this->setModificationDatetime(new DateTime());
49
    }
50
51
    /** @return int */
52
    public function getId()
53
    {
54
        return $this->id;
55
    }
56
57
    public function setId(int $id): UserEntityInterface
58
    {
59
        $this->id = $id;
60
        return $this;
61
    }
62
63
    /** @return int|null */
64
    public function getGroupId()
65
    {
66
        return $this->groupId;
67
    }
68
69
    public function setGroupId(int $groupId = null): UserEntityInterface
70
    {
71
        $this->groupId = $groupId;
72
        return $this;
73
    }
74
75
    /** @return GroupEntityInterface|null */
76
    public function getGroup()
77
    {
78
        if ($this->group && $this->group->getId() === $this->groupId) {
79
            return $this->group;
80
        } elseif (!$this->groupRepository) {
81
            throw new \Exception('Cannot fetch group without group repository');
82
        }
83
        return $this->group = $this->groupRepository->findById($this->getGroupId());
84
    }
85
86
    public function setGroup(GroupEntityInterface $group = null): UserEntityInterface
87
    {
88
        $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...
89
        $this->group = $group;
90
        return $this;
91
    }
92
93
    /** @return SessionEntityInterface[] */
94
    public function getSessions()
95
    {
96
        if (is_array($this->sessions)) {
97
            return $this->sessions;
98
        } elseif (!$this->sessionRepository) {
99
            throw new \Exception('Cannot fetch sessions without session repository');
100
        }
101
        return $this->sessions = $this->sessionRepository->findByUserId($this->getId());
102
    }
103
104
    /** @return string|null */
105
    public function getStatus()
106
    {
107
        return $this->status;
108
    }
109
110
    public function setStatus(string $status): UserEntityInterface
111
    {
112
        $this->status = $status;
113
        return $this;
114
    }
115
116
    public function isAdmin(): bool
117
    {
118
        return $this->isAdmin;
119
    }
120
121
    public function setIsAdmin(bool $isAdmin): UserEntityInterface
122
    {
123
        $this->isAdmin = $isAdmin;
124
        return $this;
125
    }
126
127
    public function isActive(): bool
128
    {
129
        return $this->getStatus() === UserEntityInterface::STATUS_ACTIVE;
130
    }
131
132
    public function getEmail(): string
133
    {
134
        return $this->email ?: '';
135
    }
136
137
    public function setEmail(string $email): UserEntityInterface
138
    {
139
        $this->email = $email;
140
        return $this;
141
    }
142
143
    /** @return string */
144
    public function getPendingEmail()
145
    {
146
        return $this->pendingEmail;
147
    }
148
149
    public function setPendingEmail(string $pendingEmail): UserEntityInterface
150
    {
151
        $this->pendingEmail = $pendingEmail;
152
        return $this;
153
    }
154
155
    public function isEmailConfirmed(): bool
156
    {
157
        return $this->isEmailConfirmed;
158
    }
159
160
    public function setIsEmailConfirmed(bool $isEmailConfirmed): UserEntityInterface
161
    {
162
        $this->isEmailConfirmed = $isEmailConfirmed;
163
        return $this;
164
    }
165
166
    /** @return string */
167
    public function getEmailConfirmationToken()
168
    {
169
        return $this->emailConfirmationToken;
170
    }
171
172
    public function setEmailConfirmationToken(string $emailConfirmationToken): UserEntityInterface
173
    {
174
        $this->emailConfirmationToken = $emailConfirmationToken;
175
        return $this;
176
    }
177
178
    /** @return DateTime */
179
    public function getEmailConfirmationTokenExpirationDatetime()
180
    {
181
        return $this->emailConfirmationTokenExpirationDatetime;
182
    }
183
184
    public function setEmailConfirmationTokenExpirationDatetime(
185
        DateTime $emailConfirmationTokenExpirationDatetime
186
    ): UserEntityInterface {
187
        $this->emailConfirmationTokenExpirationDatetime = $emailConfirmationTokenExpirationDatetime;
188
        return $this;
189
    }
190
191
    /** @return DateTime */
192
    public function getLastEmailTokenGeneratedDatetime()
193
    {
194
        return $this->lastEmailTokenGeneratedDatetime;
195
    }
196
197
    public function setLastEmailTokenGeneratedDatetime(
198
        DateTime $lastEmailTokenGeneratedDatetime
199
    ): UserEntityInterface {
200
        $this->lastEmailTokenGeneratedDatetime = $lastEmailTokenGeneratedDatetime;
201
        return $this;
202
    }
203
204
    public function canGenerateNewEmailConfirmationToken(): bool
205
    {
206
        $lastGenerated = $this->getLastEmailTokenGeneratedDatetime();
207
        return (
208
            empty($lastGenerated) ||
209
            (new DateTime())->getTimestamp() - $lastGenerated->getTimestamp() > UserEntityInterface::EMAIL_COOLDOWN
210
        );
211
    }
212
213
    public function generateEmailConfirmationToken(): UserEntityInterface
214
    {
215
        if ($this->canGenerateNewEmailConfirmationToken()) {
216
            $this->setEmailConfirmationToken(Token::generate(40));
217
            $this->setLastEmailTokenGeneratedDatetime(new DateTime());
218
        }
219
        return $this;
220
    }
221
222
    /** @return string */
223
    public function getDeletedEmail()
224
    {
225
        return $this->deletedEmail;
226
    }
227
228
    public function setDeletedEmail(string $deletedEmail): UserEntityInterface
229
    {
230
        $this->deletedEmail = $deletedEmail;
231
        return $this;
232
    }
233
234
    /** @return string */
235
    public function getPassword()
236
    {
237
        return $this->password;
238
    }
239
240
    public function setPassword(string $password): UserEntityInterface
241
    {
242
        $this->password = $password;
243
        $this->hashPassword();
244
        return $this;
245
    }
246
247
    /** @return string */
248
    public function getPasswordResetToken()
249
    {
250
        return $this->passwordResetToken;
251
    }
252
253
    public function setPasswordResetToken(string $passwordResetToken): UserEntityInterface
254
    {
255
        $this->passwordResetToken = $passwordResetToken;
256
        return $this;
257
    }
258
259
    /** @return DateTime */
260
    public function getPasswordResetTokenExpirationDatetime()
261
    {
262
        return $this->passwordResetTokenExpirationDatetime;
263
    }
264
265
    public function setPasswordResetTokenExpirationDatetime(
266
        DateTime $passwordResetTokenExpirationDatetime
267
    ): UserEntityInterface {
268
        $this->passwordResetTokenExpirationDatetime = $passwordResetTokenExpirationDatetime;
269
        return $this;
270
    }
271
272
    /** @return DateTime */
273
    public function getLastPasswordResetTokenGeneratedDatetime()
274
    {
275
        return $this->lastPasswordResetTokenGeneratedDatetime;
276
    }
277
278
    public function setLastPasswordResetTokenGeneratedDatetime(
279
        DateTime $lastPasswordResetTokenGeneratedDatetime
280
    ): UserEntityInterface {
281
        $this->lastPasswordResetTokenGeneratedDatetime = $lastPasswordResetTokenGeneratedDatetime;
282
        return $this;
283
    }
284
285
    public function canGenerateNewResetPasswordToken(): bool
286
    {
287
        $lastGenerated = $this->getLastPasswordResetTokenGeneratedDatetime();
288
        return (
289
            empty($lastGenerated) ||
290
            (new DateTime())->getTimestamp() - $lastGenerated->getTimestamp() > UserEntityInterface::EMAIL_COOLDOWN
291
        );
292
    }
293
294
    public function generatePasswordResetToken(): UserEntityInterface
295
    {
296
        if ($this->canGenerateNewResetPasswordToken()) {
297
            $this->setPasswordResetToken(Token::generate(40));
298
            $this->setLastPasswordResetTokenGeneratedDatetime(new DateTime());
299
        }
300
        return $this;
301
    }
302
303
    protected function hashPassword(): UserEntityInterface
304
    {
305
        $this->password = password_hash(
306
            (string) $this->password,
307
            PASSWORD_DEFAULT
308
        );
309
        return $this;
310
    }
311
312
    public function testPassword(string $password): bool
313
    {
314
        return password_verify($password, $this->password);
315
    }
316
317
    public function getCreationDatetime(): DateTime
318
    {
319
        return $this->creationDatetime;
320
    }
321
322
    public function setCreationDatetime(DateTime $creationDatetime): UserEntityInterface
323
    {
324
        $this->creationDatetime = $creationDatetime;
325
        return $this;
326
    }
327
328
    public function getModificationDatetime(): DateTime
329
    {
330
        return $this->modificationDatetime;
331
    }
332
333
    public function setModificationDatetime(DateTime $modificationDatetime): UserEntityInterface
334
    {
335
        $this->modificationDatetime = $modificationDatetime;
336
        return $this;
337
    }
338
339
    public function setGroupRepository(GroupRepositoryInterface $groupRepository): UserEntityInterface
340
    {
341
        $this->groupRepository = $groupRepository;
342
        return $this;
343
    }
344
345
    public function setSessionRepository(SessionRepositoryInterface $sessionRepository): UserEntityInterface
346
    {
347
        $this->sessionRepository = $sessionRepository;
348
        return $this;
349
    }
350
351
    public function toArray(): array
352
    {
353
        return [
354
            'id' => $this->getId(),
355
            'groupId' => $this->getGroupId(),
356
            'status' => $this->getStatus(),
357
            'isAdmin' => $this->isAdmin(),
358
            'email' => $this->getEmail(),
359
            'pendingEmail' => $this->getPendingEmail(),
360
            'deletedEmail' => $this->getDeletedEmail(),
361
            'isEmailConfirmed' => $this->isEmailConfirmed(),
362
            'emailConfirmationToken' => $this->getEmailConfirmationToken(),
363
            'emailConfirmationTokenExpirationDatetime' => $this->getEmailConfirmationTokenExpirationDatetime() ?
364
                $this->getEmailConfirmationTokenExpirationDatetime()->format('Y-m-d H:i:s') : null,
365
            'lastEmailTokenGeneratedDatetime' => $this->getLastEmailTokenGeneratedDatetime() ?
366
                $this->getLastEmailTokenGeneratedDatetime()->format('Y-m-d H:i:s') : null,
367
            'password' => $this->getPassword(),
368
            'passwordResetToken' => $this->getPasswordResetToken(),
369
            'passwordResetTokenExpirationDatetime' => $this->getPasswordResetTokenExpirationDatetime() ?
370
                $this->getPasswordResetTokenExpirationDatetime()->format('Y-m-d H:i:s') : null,
371
            'lastPasswordResetTokenGeneratedDatetime' => $this->getLastPasswordResetTokenGeneratedDatetime() ?
372
                $this->getLastPasswordResetTokenGeneratedDatetime()->format('Y-m-d H:i:s') : null,
373
            'creationDatetime' => $this->getCreationDatetime()->format('Y-m-d H:i:s'),
374
            'modificationDatetime' => $this->getModificationDatetime()->format('Y-m-d H:i:s'),
375
        ];
376
    }
377
378
    public function jsonSerialize()
379
    {
380
        return array_intersect_key(
381
            $this->toArray(),
382
            [
383
                'id' => null,
384
                'groupId' => null,
385
                'status' => null,
386
                'isAdmin' => null,
387
                'email' => null,
388
                'isEmailConfirmed' => null,
389
                'creationDatetime' => null,
390
                'modificationDatetime' => null,
391
            ]
392
        );
393
    }
394
}
395