Passed
Push — dev ( 0629ba...5a863f )
by Nico
31:58 queued 24:40
created

PrivateMessageSender::send()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 7.2269

Importance

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