-
-
Notifications
You must be signed in to change notification settings - Fork 682
Expand file tree
/
Copy pathUpdateMeHandler.php
More file actions
116 lines (100 loc) · 4.03 KB
/
Copy pathUpdateMeHandler.php
File metadata and controls
116 lines (100 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
namespace HiEvents\Services\Application\Handlers\User;
use HiEvents\DomainObjects\UserDomainObject;
use HiEvents\Exceptions\PasswordInvalidException;
use HiEvents\Mail\User\ConfirmEmailChangeMail;
use HiEvents\Repository\Interfaces\UserRepositoryInterface;
use HiEvents\Services\Application\Handlers\User\DTO\UpdateMeDTO;
use HiEvents\Services\Infrastructure\Encryption\EncryptedPayloadService;
use Illuminate\Contracts\Hashing\Hasher;
use Illuminate\Contracts\Mail\Mailer;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
readonly class UpdateMeHandler
{
public function __construct(
private UserRepositoryInterface $userRepository,
private Hasher $hasher,
private Mailer $mailer,
private EncryptedPayloadService $encryptedPayloadService,
)
{
}
/**
* @throws PasswordInvalidException
*/
public function handle(UpdateMeDTO $updateUserData): UserDomainObject
{
$existingUser = $this->getExistingUser($updateUserData);
$updateArray = [];
if ($this->isChangingPassword($updateUserData)) {
$this->validateCurrentPassword($updateUserData, $existingUser);
$updateArray['password'] = $this->hasher->make($updateUserData->password);
}
if ($this->isUpdatingDetails($updateUserData)) {
$updateArray = [
'first_name' => $updateUserData->first_name,
'last_name' => $updateUserData->last_name,
'timezone' => $updateUserData->timezone,
'locale' => $updateUserData->locale,
];
if ($this->isChangingEmail($updateUserData, $existingUser)) {
$updateArray['pending_email'] = $updateUserData->email;
$this->sendEmailChangeConfirmation($existingUser);
}
}
if ($updateUserData->marketing_opt_in !== null) {
$updateArray['marketing_opted_in_at'] = $updateUserData->marketing_opt_in
? now()->toDateTimeString()
: null;
}
$this->userRepository->updateWhere(
attributes: $updateArray,
where: [
'id' => $updateUserData->id,
]
);
return $this->userRepository->findByIdAndAccountId($updateUserData->id, $updateUserData->account_id);
}
private function isChangingPassword(UpdateMeDTO $updateUserData): bool
{
return $updateUserData->password !== null && $updateUserData->current_password !== null;
}
/**
* @throws PasswordInvalidException
*/
private function validateCurrentPassword(UpdateMeDTO $updateUserData, UserDomainObject $existingUser): void
{
if (!$this->hasher->check($updateUserData->current_password, $existingUser->getPassword())) {
throw new PasswordInvalidException('Current password is invalid');
}
}
private function isChangingEmail(UpdateMeDTO $updateUserData, UserDomainObject $existingUser): bool
{
return $updateUserData->email !== $existingUser->getEmail();
}
private function getExistingUser(UpdateMeDTO $updateUserData): UserDomainObject
{
return $this->userRepository->findByIdAndAccountId(
$updateUserData->id,
$updateUserData->account_id
);
}
private function sendEmailChangeConfirmation(UserDomainObject $existingUser): void
{
$this->mailer
->to($existingUser->getEmail())
->locale($existingUser->getLocale())
->send(new ConfirmEmailChangeMail($existingUser, $this->encryptedPayloadService->encryptPayload([
'id' => $existingUser->getId(),
]))
);
}
/**
* @param UpdateMeDTO $updateUserData
* @return bool
*/
private function isUpdatingDetails(UpdateMeDTO $updateUserData): bool
{
return $updateUserData->first_name !== null || $updateUserData->last_name !== null || $updateUserData->timezone !== null || $updateUserData->email !== null;
}
}