MessageQueuer::createMessage()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 18
ccs 13
cts 13
cp 1
rs 9.8666
cc 2
nc 2
nop 5
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Service;
6
7
use Application\DBAL\Types\MessageTypeType;
8
use Application\Model\Bookable;
9
use Application\Model\Booking;
10
use Application\Model\Message;
11
use Application\Model\User;
12
use Application\Repository\UserRepository;
13
use Doctrine\ORM\EntityManager;
14
use Ecodev\Felix\Service\MessageRenderer;
15
16
/**
17
 * Service to queue new message for pre-defined purposes.
18
 */
19
class MessageQueuer
20
{
21
    private bool $toFamilyOwner = false;
22
23
    private readonly UserRepository $userRepository;
24
25 13
    public function __construct(private readonly EntityManager $entityManager, private readonly MessageRenderer $messageRenderer)
26
    {
27 13
        $this->userRepository = $this->entityManager->getRepository(User::class);
0 ignored issues
show
Bug introduced by
The property userRepository is declared read-only in Application\Service\MessageQueuer.
Loading history...
28
    }
29
30 3
    public function queueRegister(User $user): ?Message
31
    {
32 3
        $subject = 'Demande de création de compte au Club Nautique Ichtus';
33 3
        $mailParams = [
34 3
            'token' => $user->createToken(),
35 3
        ];
36
37 3
        $message = $this->createMessage($user, $subject, MessageTypeType::REGISTER, $mailParams);
38
39 3
        return $message;
40
    }
41
42 2
    public function queueUnregister(User $admin, User $unregisteredUser): ?Message
43
    {
44 2
        $subject = 'Démission';
45 2
        $mailParams = [
46 2
            'unregisteredUser' => $unregisteredUser,
47 2
        ];
48
49 2
        $message = $this->createMessage($admin, $subject, MessageTypeType::UNREGISTER, $mailParams);
50
51 2
        return $message;
52
    }
53
54
    /**
55
     * Queue a reset password email to specified user.
56
     *
57
     * @param User $user The user for which a password reset will be done
58
     */
59 7
    public function queueResetPassword(User $user): ?Message
60
    {
61 7
        $subject = 'Demande de modification de mot de passe';
62 7
        $mailParams = [
63 7
            'token' => $user->createToken(),
64 7
        ];
65
66 7
        $message = $this->createMessage($user, $subject, MessageTypeType::RESET_PASSWORD, $mailParams);
67
68 7
        return $message;
69
    }
70
71
    /**
72
     * @param Bookable[] $bookables
73
     */
74 3
    public function queueBalance(User $user, iterable $bookables): ?Message
75
    {
76 3
        $subject = 'Balance de compte';
77 3
        $mailParams = [
78 3
            'bookables' => $bookables,
79 3
        ];
80
81 3
        $message = $this->createMessage($user, $subject, MessageTypeType::BALANCE, $mailParams);
82
83 3
        return $message;
84
    }
85
86 3
    public function queueLeaveFamily(User $user): ?Message
87
    {
88 3
        $subject = 'Ménage quitté';
89 3
        $mailParams = [];
90
91 3
        $message = $this->createMessage($user, $subject, MessageTypeType::LEAVE_FAMILY, $mailParams);
92
93 3
        return $message;
94
    }
95
96 3
    public function queueAdminLeaveFamily(User $independentUser): ?Message
97
    {
98 3
        $subject = 'Ménage quitté';
99 3
        $mailParams = ['independentUser' => $independentUser];
100
101 3
        $message = $this->createMessage(null, $subject, MessageTypeType::ADMIN_LEAVE_FAMILY, $mailParams, '[email protected]');
102
103 3
        return $message;
104
    }
105
106
    /**
107
     * Create a message by rendering the template.
108
     */
109 19
    private function createMessage(?User $user, string $subject, string $type, array $mailParams, ?string $email = null): ?Message
110
    {
111 19
        $email = $this->getEmail($user, $email);
112 19
        if (!$email) {
113 2
            return null;
114
        }
115
116 17
        $content = $this->messageRenderer->render($user, $email, $subject, $type, $mailParams);
117
118 17
        $message = new Message();
119 17
        $message->setType($type);
120 17
        $message->setRecipient($user);
121 17
        $message->setSubject($subject);
122 17
        $message->setBody($content);
123 17
        $message->setEmail($email);
124 17
        $this->entityManager->persist($message);
125
126 17
        return $message;
127
    }
128
129
    /**
130
     * @param User[] $users
131
     */
132 2
    private function queueBalanceForEachUsers(array $users): int
133
    {
134 2
        foreach ($users as $user) {
135 1
            $bookables = $user->getRunningBookings()->map(fn (Booking $booking) => $booking->getBookable());
136
137 1
            $this->queueBalance($user, $bookables);
138
        }
139
140 2
        return count($users);
141
    }
142
143 1
    public function queueAllBalance(): int
144
    {
145 1
        $users = $this->userRepository->getAllToQueueBalanceMessage();
146
147 1
        return $this->queueBalanceForEachUsers($users);
148
    }
149
150 1
    public function queueNegativeBalance(): int
151
    {
152
        /** @var UserRepository $userRepository */
153 1
        $userRepository = $this->entityManager->getRepository(User::class);
154 1
        $users = $userRepository->getAllToQueueBalanceMessage(true);
155
156 1
        return $this->queueBalanceForEachUsers($users);
157
    }
158
159 19
    private function getEmail(?User $user, ?string $email): ?string
160
    {
161 19
        $this->toFamilyOwner = false;
162 19
        $email ??= $user?->getEmail();
163
164
        // Fallback to family owner if any
165 19
        if (!$email && $user?->getOwner()) {
166 3
            $email = $this->userRepository->getAclFilter()->runWithoutAcl(fn () => $user->getOwner()->getEmail());
0 ignored issues
show
Bug introduced by
The method getOwner() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

166
            $email = $this->userRepository->getAclFilter()->runWithoutAcl(fn () => $user->/** @scrutinizer ignore-call */ getOwner()->getEmail());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
167
168 3
            $this->toFamilyOwner = true;
169
        }
170
171 19
        return $email;
172
    }
173
174
    /**
175
     * Whether the last sent email was sent to family owner instead of original recipient.
176
     */
177 4
    public function wasToFamilyOwner(): bool
178
    {
179 4
        return $this->toFamilyOwner;
180
    }
181
}
182