Passed
Push — dev ( 41c964...d79ab9 )
by Janko
13:43 queued 04:40
created

PrivateMessageSender::send()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7.2576

Importance

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