Passed
Push — 7.x ( 39b4d4...384570 )
by Torben
43:44
created

getAdminMessageTemplateSubject()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 28
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 24
nc 6
nop 2
dl 0
loc 28
rs 8.9137
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace DERHANSEN\SfEventMgt\Service;
13
14
use DERHANSEN\SfEventMgt\Domain\Model\CustomNotificationLog;
15
use DERHANSEN\SfEventMgt\Domain\Model\Dto\CustomNotification;
16
use DERHANSEN\SfEventMgt\Domain\Model\Event;
17
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
18
use DERHANSEN\SfEventMgt\Domain\Repository\CustomNotificationLogRepository;
19
use DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository;
20
use DERHANSEN\SfEventMgt\Event\AfterAdminMessageSentEvent;
21
use DERHANSEN\SfEventMgt\Event\AfterUserMessageSentEvent;
22
use DERHANSEN\SfEventMgt\Event\ModifyCustomNotificationLogEvent;
23
use DERHANSEN\SfEventMgt\Event\ModifyUserMessageAttachmentsEvent;
24
use DERHANSEN\SfEventMgt\Event\ModifyUserMessageSenderEvent;
25
use DERHANSEN\SfEventMgt\Service\Notification\AttachmentService;
26
use DERHANSEN\SfEventMgt\Utility\MessageRecipient;
27
use DERHANSEN\SfEventMgt\Utility\MessageType;
28
use Psr\EventDispatcher\EventDispatcherInterface;
29
use Psr\Http\Message\ServerRequestInterface;
30
use TYPO3\CMS\Core\Http\ApplicationType;
31
use TYPO3\CMS\Core\Utility\GeneralUtility;
32
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
33
34
class NotificationService
35
{
36
    protected RegistrationRepository $registrationRepository;
37
    protected EmailService $emailService;
38
    protected HashService $hashService;
39
    protected FluidStandaloneService $fluidStandaloneService;
40
    protected CustomNotificationLogRepository $customNotificationLogRepository;
41
    protected AttachmentService $attachmentService;
42
    protected EventDispatcherInterface $eventDispatcher;
43
44
    public function injectAttachmentService(AttachmentService $attachmentService): void
45
    {
46
        $this->attachmentService = $attachmentService;
47
    }
48
49
    public function injectCustomNotificationLogRepository(
50
        CustomNotificationLogRepository $customNotificationLogRepository
51
    ): void {
52
        $this->customNotificationLogRepository = $customNotificationLogRepository;
53
    }
54
55
    public function injectEmailService(EmailService $emailService): void
56
    {
57
        $this->emailService = $emailService;
58
    }
59
60
    public function injectFluidStandaloneService(FluidStandaloneService $fluidStandaloneService): void
61
    {
62
        $this->fluidStandaloneService = $fluidStandaloneService;
63
    }
64
65
    public function injectHashService(HashService $hashService): void
66
    {
67
        $this->hashService = $hashService;
68
    }
69
70
    public function injectRegistrationRepository(RegistrationRepository $registrationRepository): void
71
    {
72
        $this->registrationRepository = $registrationRepository;
73
    }
74
75
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher): void
76
    {
77
        $this->eventDispatcher = $eventDispatcher;
78
    }
79
80
    /**
81
     * Sends a custom notification defined by the given customNotification key
82
     * to all confirmed users of the event. Returns the number of notifications sent.
83
     */
84
    public function sendCustomNotification(
85
        Event $event,
86
        CustomNotification $customNotification,
87
        array $settings = []
88
    ): int {
89
        if ($this->cantSendCustomNotification($settings, $customNotification)) {
90
            return 0;
91
        }
92
        $count = 0;
93
94
        $customNotificationSettings = $settings['notification']['customNotifications'] ?? [];
95
        $constraints = $customNotificationSettings[$customNotification->getTemplate()]['constraints'] ?? [];
96
        $registrations = $this->registrationRepository->findNotificationRegistrations(
97
            $event,
98
            $customNotification,
99
            $constraints
100
        );
101
102
        foreach ($registrations as $registration) {
103
            /** @var Registration $registration */
104
            $result = $this->sendUserMessage(
105
                $event,
106
                $registration,
107
                $settings,
108
                MessageType::CUSTOM_NOTIFICATION,
109
                $customNotification
110
            );
111
            if ($result) {
112
                $count += 1;
113
            }
114
        }
115
116
        return $count;
117
    }
118
119
    /**
120
     * Returns true if conditions are not met to send a custom notification
121
     */
122
    protected function cantSendCustomNotification(
123
        array $settings,
124
        CustomNotification $customNotification
125
    ): bool {
126
        return $customNotification->getTemplate() === '' || empty($settings);
127
    }
128
129
    /**
130
     * Adds a logentry to the custom notification log
131
     */
132
    public function createCustomNotificationLogentry(
133
        Event $event,
134
        string $details,
135
        int $emailsSent,
136
        CustomNotification $customNotification
137
    ): void {
138
        $notificationlogEntry = new CustomNotificationLog();
139
        $notificationlogEntry->setPid($event->getPid());
0 ignored issues
show
Bug introduced by
It seems like $event->getPid() can also be of type null; however, parameter $pid of TYPO3\CMS\Extbase\Domain...tDomainObject::setPid() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

139
        $notificationlogEntry->setPid(/** @scrutinizer ignore-type */ $event->getPid());
Loading history...
140
        $notificationlogEntry->setEvent($event);
141
        $notificationlogEntry->setDetails($details);
142
        $notificationlogEntry->setEmailsSent($emailsSent);
143
        $notificationlogEntry->setCruserId($GLOBALS['BE_USER']->user['uid'] ?? 0);
144
145
        $modifyCustomNotificationLogEntry = new ModifyCustomNotificationLogEvent(
146
            $notificationlogEntry,
147
            $event,
148
            $details,
149
            $customNotification
150
        );
151
        $this->eventDispatcher->dispatch($modifyCustomNotificationLogEntry);
152
        $notificationlogEntry = $modifyCustomNotificationLogEntry->getCustomNotificationLog();
153
154
        $this->customNotificationLogRepository->add($notificationlogEntry);
155
    }
156
157
    /**
158
     * Sends a message to the user based on the given type
159
     */
160
    public function sendUserMessage(
161
        Event $event,
162
        Registration $registration,
163
        array $settings,
164
        int $type,
165
        ?CustomNotification $customNotification = null
166
    ): bool {
167
        [$template, $subject] = $this->getUserMessageTemplateSubject(
168
            $settings,
169
            $type,
170
            $customNotification
171
        );
172
173
        if ((bool)($settings['notification']['disabled'] ?? false) || !str_ends_with($template, '.html')) {
174
            return false;
175
        }
176
177
        $additionalBodyVariables = [
178
            'customNotification' => $customNotification,
179
        ];
180
181
        if (!$registration->isIgnoreNotifications()) {
182
            $body = $this->getNotificationBody($event, $registration, $template, $settings, $additionalBodyVariables);
183
            $subject = $this->fluidStandaloneService->parseStringFluid(
184
                $subject,
185
                [
186
                    'event' => $event,
187
                    'registration' => $registration,
188
                ]
189
            );
190
            $attachments = $this->attachmentService->getAttachments(
191
                $settings,
192
                $registration,
193
                $type,
194
                MessageRecipient::USER
195
            );
196
197
            // Get iCal attachment if configured
198
            $iCalAttachment = $this->attachmentService->getICalAttachment(
199
                $settings,
200
                $registration,
201
                $type,
202
                MessageRecipient::USER
203
            );
204
205
            if ($iCalAttachment !== '') {
206
                $attachments[] = $iCalAttachment;
207
            }
208
209
            $modifyUserMessageSenderEvent = new ModifyUserMessageSenderEvent(
210
                $settings['notification']['senderName'] ?? '',
211
                $settings['notification']['senderEmail'] ?? '',
212
                $settings['notification']['replyToEmail'] ?? '',
213
                $registration,
214
                $type,
215
                $this
216
            );
217
            $this->eventDispatcher->dispatch($modifyUserMessageSenderEvent);
218
            $senderName = $modifyUserMessageSenderEvent->getSenderName();
219
            $senderEmail = $modifyUserMessageSenderEvent->getSenderEmail();
220
            $replyToEmail = $modifyUserMessageSenderEvent->getReplyToEmail();
221
222
            $modifyUserAttachmentsEvent = new ModifyUserMessageAttachmentsEvent(
223
                $attachments,
224
                $registration,
225
                $type,
226
                $this
227
            );
228
            $this->eventDispatcher->dispatch($modifyUserAttachmentsEvent);
229
            $attachments = $modifyUserAttachmentsEvent->getAttachments();
230
231
            $result = $this->emailService->sendEmailMessage(
232
                $senderEmail,
233
                $registration->getEmail(),
234
                $subject,
235
                $body,
236
                $senderName,
237
                $attachments,
238
                $replyToEmail
239
            );
240
241
            $afterUserMessageSentEvent = new AfterUserMessageSentEvent(
242
                $registration,
243
                $body,
244
                $subject,
245
                $attachments,
246
                $senderName,
247
                $senderEmail,
248
                $replyToEmail,
249
                $this
250
            );
251
            $this->eventDispatcher->dispatch($afterUserMessageSentEvent);
252
253
            // Cleanup iCal attachment if available
254
            if ($iCalAttachment !== '') {
255
                GeneralUtility::unlink_tempfile($iCalAttachment);
256
            }
257
258
            return $result;
259
        }
260
261
        return false;
262
    }
263
264
    /**
265
     * Returns an array with template and subject for the user message
266
     */
267
    protected function getUserMessageTemplateSubject(
268
        array $settings,
269
        int $type,
270
        ?CustomNotification $customNotification = null
271
    ): array {
272
        if ($type === MessageType::CUSTOM_NOTIFICATION && $customNotification === null) {
273
            return ['', ''];
274
        }
275
276
        switch ($type) {
277
            case MessageType::REGISTRATION_NEW:
278
                $template = 'Notification/User/RegistrationNew.html';
279
                $subject = $settings['notification']['registrationNew']['userSubject'] ?? '';
280
                break;
281
            case MessageType::REGISTRATION_WAITLIST_NEW:
282
                $template = 'Notification/User/RegistrationWaitlistNew.html';
283
                $subject = $settings['notification']['registrationWaitlistNew']['userSubject'] ?? '';
284
                break;
285
            case MessageType::REGISTRATION_CONFIRMED:
286
                $template = 'Notification/User/RegistrationConfirmed.html';
287
                $subject = $settings['notification']['registrationConfirmed']['userSubject'] ?? '';
288
                break;
289
            case MessageType::REGISTRATION_WAITLIST_CONFIRMED:
290
                $template = 'Notification/User/RegistrationWaitlistConfirmed.html';
291
                $subject = $settings['notification']['registrationWaitlistConfirmed']['userSubject'] ?? '';
292
                break;
293
            case MessageType::REGISTRATION_CANCELLED:
294
                $template = 'Notification/User/RegistrationCancelled.html';
295
                $subject = $settings['notification']['registrationCancelled']['userSubject'] ?? '';
296
                break;
297
            case MessageType::REGISTRATION_WAITLIST_MOVE_UP:
298
                $template = 'Notification/User/RegistrationWaitlistMoveUp.html';
299
                $subject = $settings['notification']['registrationWaitlistMoveUp']['userSubject'] ?? '';
300
                break;
301
            case MessageType::CUSTOM_NOTIFICATION:
302
                $customNotificationSettings = $settings['notification']['customNotifications'] ?? [];
303
                $templateKey = $customNotification->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate() 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

303
                /** @scrutinizer ignore-call */ 
304
                $templateKey = $customNotification->getTemplate();

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...
304
                $template = 'Notification/User/Custom/' . $customNotificationSettings[$templateKey]['template'] ?? '';
305
                $subject = $customNotificationSettings[$templateKey]['subject'] ?? '';
306
                if ($customNotification->getOverwriteSubject() !== '') {
307
                    $subject = $customNotification->getOverwriteSubject();
308
                }
309
                break;
310
            default:
311
                $template = '';
312
                $subject = '';
313
        }
314
315
        return [
316
            $template,
317
            $subject,
318
        ];
319
    }
320
321
    /**
322
     * Sends a message to the admin based on the given type. Returns true, if the message was sent, otherwise false
323
     */
324
    public function sendAdminMessage(Event $event, Registration $registration, array $settings, int $type): bool
325
    {
326
        [$template, $subject] = $this->getAdminMessageTemplateSubject($settings, $type);
327
328
        if ((bool)($settings['notification']['disabled'] ?? false) ||
329
            ($event->getNotifyAdmin() === false && $event->getNotifyOrganisator() === false)
330
        ) {
331
            return false;
332
        }
333
334
        $allEmailsSent = true;
335
        $body = $this->getNotificationBody($event, $registration, $template, $settings);
336
        $subject = $this->fluidStandaloneService->parseStringFluid(
337
            $subject,
338
            [
339
                'event' => $event,
340
                'registration' => $registration,
341
            ]
342
        );
343
        $attachments = $this->attachmentService->getAttachments(
344
            $settings,
345
            $registration,
346
            $type,
347
            MessageRecipient::ADMIN
348
        );
349
350
        $senderName = $settings['notification']['senderName'] ?? '';
351
        $senderEmail = $settings['notification']['senderEmail'] ?? '';
352
        if ((bool)($settings['notification']['registrationDataAsSenderForAdminEmails'] ?? false)) {
353
            $senderName = $registration->getFullname();
354
            $senderEmail = $registration->getEmail();
355
        }
356
357
        if ($event->getNotifyAdmin()) {
358
            $adminEmailArr = GeneralUtility::trimExplode(',', $settings['notification']['adminEmail'] ?? '', true);
359
            foreach ($adminEmailArr as $adminEmail) {
360
                $allEmailsSent = $allEmailsSent && $this->emailService->sendEmailMessage(
361
                    $senderEmail,
362
                    $adminEmail,
363
                    $subject,
364
                    $body,
365
                    $senderName,
366
                    $attachments
367
                );
368
            }
369
        }
370
371
        if ($event->getNotifyOrganisator() && $event->getOrganisator()) {
372
            $allEmailsSent = $allEmailsSent && $this->emailService->sendEmailMessage(
373
                $senderEmail,
374
                $event->getOrganisator()->getEmail(),
375
                $subject,
376
                $body,
377
                $senderName,
378
                $attachments
379
            );
380
        }
381
382
        $afterAdminMessageSentEvent = new AfterAdminMessageSentEvent(
383
            $registration,
384
            $body,
385
            $subject,
386
            $attachments,
387
            $senderName,
388
            $senderEmail,
389
            $type,
390
            $this
391
        );
392
        $this->eventDispatcher->dispatch($afterAdminMessageSentEvent);
393
394
        return $allEmailsSent;
395
    }
396
397
    /**
398
     * Returns an array with template and subject for the admin message
399
     */
400
    protected function getAdminMessageTemplateSubject(array $settings, int $type): array
401
    {
402
        $template = 'Notification/Admin/RegistrationNew.html';
403
        $subject = $settings['notification']['registrationNew']['adminSubject'] ?? '';
404
        switch ($type) {
405
            case MessageType::REGISTRATION_WAITLIST_NEW:
406
                $template = 'Notification/Admin/RegistrationWaitlistNew.html';
407
                $subject = $settings['notification']['registrationWaitlistNew']['adminSubject'] ?? '';
408
                break;
409
            case MessageType::REGISTRATION_CONFIRMED:
410
                $template = 'Notification/Admin/RegistrationConfirmed.html';
411
                $subject = $settings['notification']['registrationConfirmed']['adminSubject'] ?? '';
412
                break;
413
            case MessageType::REGISTRATION_WAITLIST_CONFIRMED:
414
                $template = 'Notification/Admin/RegistrationWaitlistConfirmed.html';
415
                $subject = $settings['notification']['registrationWaitlistConfirmed']['adminSubject'] ?? '';
416
                break;
417
            case MessageType::REGISTRATION_CANCELLED:
418
                $template = 'Notification/Admin/RegistrationCancelled.html';
419
                $subject = $settings['notification']['registrationCancelled']['adminSubject'] ?? '';
420
                break;
421
            case MessageType::REGISTRATION_WAITLIST_MOVE_UP:
422
                $template = 'Notification/Admin/RegistrationWaitlistMoveUp.html';
423
                $subject = $settings['notification']['registrationWaitlistMoveUp']['adminSubject'] ?? '';
424
                break;
425
        }
426
427
        return [$template, $subject];
428
    }
429
430
    /**
431
     * Returns the rendered HTML for the given template
432
     */
433
    protected function getNotificationBody(
434
        Event $event,
435
        Registration $registration,
436
        string $template,
437
        array $settings,
438
        array $additionalBodyVariables = []
439
    ): string {
440
        $isBackendRequest = ($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
441
            && ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
442
443
        if ($isBackendRequest && $registration->getLanguage() !== '') {
444
            // Temporary set Language of current BE user to given language
445
            $GLOBALS['BE_USER']->uc['lang'] = $registration->getLanguage();
446
        }
447
        $defaultVariables = [
448
            'event' => $event,
449
            'registration' => $registration,
450
            'settings' => $settings,
451
            'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid()),
452
            'reghmac' => $this->hashService->appendHmac((string)$registration->getUid()),
453
        ];
454
        $variables = array_merge($additionalBodyVariables, $defaultVariables);
455
456
        return $this->fluidStandaloneService->renderTemplate($template, $variables);
457
    }
458
}
459