Passed
Pull Request — master (#1801)
by Nico
23:50
created

PrivateMessageSender::sendBroadcast()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 20
nc 3
nop 3
dl 0
loc 33
ccs 22
cts 22
cp 1
crap 3
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Message\Lib;
6
7
use InvalidArgumentException;
8
use JBBCode\Parser;
9
use Laminas\Mail\Exception\RuntimeException;
10
use Noodlehaus\ConfigInterface;
11
use Stu\Lib\Information\InformationWrapper;
12
use Stu\Lib\Mail\MailFactoryInterface;
13
use Stu\Module\Control\StuTime;
14
use Stu\Module\Logging\LoggerEnum;
15
use Stu\Module\Logging\LoggerUtilFactoryInterface;
16
use Stu\Module\Logging\LoggerUtilInterface;
17
use Stu\Module\PlayerSetting\Lib\UserEnum;
18
use Stu\Orm\Entity\PrivateMessageInterface;
19
use Stu\Orm\Entity\UserInterface;
20
use Stu\Orm\Repository\PrivateMessageFolderRepositoryInterface;
21
use Stu\Orm\Repository\PrivateMessageRepositoryInterface;
22
use Stu\Orm\Repository\UserRepositoryInterface;
23
24
final class PrivateMessageSender implements PrivateMessageSenderInterface
25
{
26
    private LoggerUtilInterface $loggerUtil;
27
28 8
    public function __construct(
29
        private PrivateMessageFolderRepositoryInterface $privateMessageFolderRepository,
30
        private PrivateMessageRepositoryInterface $privateMessageRepository,
31
        private UserRepositoryInterface $userRepository,
32
        private MailFactoryInterface $mailFactory,
33
        private ConfigInterface $config,
34
        private Parser $bbcodeParser,
35
        private StuTime $stuTime,
36
        LoggerUtilFactoryInterface $loggerUtilFactory
37
    ) {
38 8
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil();
39
    }
40
41 2
    public function send(
42
        int $senderId,
43
        int $recipientId,
44
        string|InformationWrapper $information,
45
        int $category = PrivateMessageFolderSpecialEnum::PM_SPECIAL_SYSTEM,
46
        string $href = null,
47
        bool $isRead = false
48
    ): void {
49 2
        if ($senderId === $recipientId) {
50
            return;
51
        }
52
53
        if (
54 2
            $information instanceof InformationWrapper
55 2
            && $information->isEmpty()
56
        ) {
57
            return;
58
        }
59
60 2
        $text = $information instanceof InformationWrapper ? $information->getInformationsAsString() : $information;
61
62 2
        $recipient = $this->userRepository->find($recipientId);
63 2
        $sender = $this->userRepository->find($senderId);
64
65 2
        if ($sender === null) {
66
            throw new InvalidArgumentException(sprintf('Sender with id %d does not exist', $senderId));
67
        }
68 2
        if ($recipient === null) {
69
            throw new InvalidArgumentException(sprintf('Recipient with id %d does not exist', $recipientId));
70
        }
71
72 2
        $time = $this->stuTime->time();
73
74 2
        $pm = $this->createPrivateMessage(
75 2
            $sender,
76 2
            $recipient,
77 2
            $time,
78 2
            $category,
79 2
            $text,
80 2
            $href,
81 2
            !$isRead
82 2
        );
83
84
        if (
85 2
            $category === PrivateMessageFolderSpecialEnum::PM_SPECIAL_MAIN
86 2
            && $recipient->isEmailNotification()
87
        ) {
88 1
            $this->sendEmailNotification($sender->getName(), $text, $recipient);
89
        }
90
91 2
        if ($senderId != UserEnum::USER_NOONE) {
92 2
            $this->createPrivateMessage(
93 2
                $recipient,
94 2
                $sender,
95 2
                $time,
96 2
                PrivateMessageFolderSpecialEnum::PM_SPECIAL_PMOUT,
97 2
                $text,
98 2
                null,
99 2
                false,
100 2
                $pm
101 2
            );
102
        }
103
    }
104
105 2
    public function sendBroadcast(
106
        UserInterface $sender,
107
        array $recipients,
108
        string $text
109
    ): void {
110 2
        if ($recipients === []) {
111 1
            return;
112
        }
113
114 1
        $time = $this->stuTime->time();
115
116
        //broadcast pm to every recipient
117 1
        foreach ($recipients as $recipient) {
118 1
            $this->createPrivateMessage(
119 1
                $sender,
120 1
                $recipient,
121 1
                $time,
122 1
                PrivateMessageFolderSpecialEnum::PM_SPECIAL_MAIN,
123 1
                $text,
124 1
                null,
125 1
                true
126 1
            );
127
        }
128
129
        //single item to outbox
130 1
        $this->createPrivateMessage(
131 1
            $this->userRepository->getFallbackUser(),
132 1
            $sender,
133 1
            $time,
134 1
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_PMOUT,
135 1
            $text,
136 1
            null,
137 1
            false
138 1
        );
139
    }
140
141 3
    private function createPrivateMessage(
142
        UserInterface $sender,
143
        UserInterface $recipient,
144
        int $time,
145
        int $category,
146
        string $text,
147
        ?string $href,
148
        bool $new,
149
        PrivateMessageInterface $inboxPm = null
150
    ): PrivateMessageInterface {
151 3
        $folder = $this->privateMessageFolderRepository->getByUserAndSpecial($recipient->getId(), $category);
152
153 3
        if ($folder === null) {
154
            throw new InvalidArgumentException(sprintf('Folder with user_id %d and category %d does not exist', $recipient->getId(), $category));
155
        }
156
157 3
        $pm = $this->privateMessageRepository->prototype();
158 3
        $pm->setDate($time);
159 3
        $pm->setCategory($folder);
160 3
        $pm->setText($text);
161 3
        $pm->setHref($href);
162 3
        $pm->setRecipient($recipient);
163 3
        $pm->setSender($sender);
164 3
        $pm->setNew($new);
165 3
        if ($inboxPm !== null) {
166 2
            $pm->setInboxPm($inboxPm);
167
        }
168
169 3
        $this->privateMessageRepository->save($pm);
170
171 3
        return $pm;
172
    }
173
174 1
    private function sendEmailNotification(string $senderName, string $message, UserInterface $user): void
175
    {
176 1
        $mail = $this->mailFactory->createMessage();
177
178 1
        $mail->addTo($user->getEmail());
179 1
        $senderNameAsText = $this->bbcodeParser->parse($senderName)->getAsText();
180 1
        $mail->setSubject(sprintf(_('Neue Privatnachricht von Spieler %s'), $senderNameAsText));
181 1
        $mail->setFrom($this->config->get('game.email_sender_address'));
182 1
        $mail->setBody($message);
183
184
        try {
185 1
            $transport = $this->mailFactory->createSendmail();
186 1
            $transport->send($mail);
187
        } catch (RuntimeException $e) {
188
            $this->loggerUtil->init("mail", LoggerEnum::LEVEL_ERROR);
189
            $this->loggerUtil->log($e->getMessage());
190
        }
191
    }
192
}
193