NotificationService::injectAttachmentService()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Securi...ryptography\HashService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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 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());
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
                $customNotification
196
            );
197
198
            // Get iCal attachment if configured
199
            $iCalAttachment = $this->attachmentService->getICalAttachment(
200
                $settings,
201
                $registration,
202
                $type,
203
                MessageRecipient::USER,
204
                $customNotification
205
            );
206
207
            if ($iCalAttachment !== '') {
208
                $attachments[] = $iCalAttachment;
209
            }
210
211
            $modifyUserMessageSenderEvent = new ModifyUserMessageSenderEvent(
212
                $settings['notification']['senderName'] ?? '',
213
                $settings['notification']['senderEmail'] ?? '',
214
                $settings['notification']['replyToEmail'] ?? '',
215
                $subject,
216
                $body,
217
                $registration,
218
                $type,
219
                $this
220
            );
221
            $this->eventDispatcher->dispatch($modifyUserMessageSenderEvent);
222
            $subject = $modifyUserMessageSenderEvent->getSubject();
223
            $body = $modifyUserMessageSenderEvent->getBody();
224
225
            $senderName = $modifyUserMessageSenderEvent->getSenderName();
226
            $senderEmail = $modifyUserMessageSenderEvent->getSenderEmail();
227
            $replyToEmail = $modifyUserMessageSenderEvent->getReplyToEmail();
228
229
            $modifyUserAttachmentsEvent = new ModifyUserMessageAttachmentsEvent(
230
                $attachments,
231
                $registration,
232
                $type,
233
                $settings,
234
                $customNotification,
235
                $this
236
            );
237
            $this->eventDispatcher->dispatch($modifyUserAttachmentsEvent);
238
            $attachments = $modifyUserAttachmentsEvent->getAttachments();
239
240
            $result = $this->emailService->sendEmailMessage(
241
                $senderEmail,
242
                $registration->getEmail(),
243
                $subject,
244
                $body,
245
                $senderName,
246
                $attachments,
247
                $replyToEmail
248
            );
249
250
            $afterUserMessageSentEvent = new AfterUserMessageSentEvent(
251
                $registration,
252
                $body,
253
                $subject,
254
                $attachments,
255
                $senderName,
256
                $senderEmail,
257
                $replyToEmail,
258
                $this
259
            );
260
            $this->eventDispatcher->dispatch($afterUserMessageSentEvent);
261
262
            // Cleanup iCal attachment if available
263
            if ($iCalAttachment !== '') {
264
                GeneralUtility::unlink_tempfile($iCalAttachment);
265
            }
266
267
            return $result;
268
        }
269
270
        return false;
271
    }
272
273
    /**
274
     * Returns an array with template and subject for the user message
275
     */
276
    protected function getUserMessageTemplateSubject(
277
        array $settings,
278
        int $type,
279
        ?CustomNotification $customNotification = null
280
    ): array {
281
        if ($type === MessageType::CUSTOM_NOTIFICATION && $customNotification === null) {
282
            return ['', ''];
283
        }
284
285
        switch ($type) {
286
            case MessageType::REGISTRATION_NEW:
287
                $template = 'Notification/User/RegistrationNew.html';
288
                $subject = $settings['notification']['registrationNew']['userSubject'] ?? '';
289
                break;
290
            case MessageType::REGISTRATION_WAITLIST_NEW:
291
                $template = 'Notification/User/RegistrationWaitlistNew.html';
292
                $subject = $settings['notification']['registrationWaitlistNew']['userSubject'] ?? '';
293
                break;
294
            case MessageType::REGISTRATION_CONFIRMED:
295
                $template = 'Notification/User/RegistrationConfirmed.html';
296
                $subject = $settings['notification']['registrationConfirmed']['userSubject'] ?? '';
297
                break;
298
            case MessageType::REGISTRATION_WAITLIST_CONFIRMED:
299
                $template = 'Notification/User/RegistrationWaitlistConfirmed.html';
300
                $subject = $settings['notification']['registrationWaitlistConfirmed']['userSubject'] ?? '';
301
                break;
302
            case MessageType::REGISTRATION_CANCELLED:
303
                $template = 'Notification/User/RegistrationCancelled.html';
304
                $subject = $settings['notification']['registrationCancelled']['userSubject'] ?? '';
305
                break;
306
            case MessageType::REGISTRATION_WAITLIST_MOVE_UP:
307
                $template = 'Notification/User/RegistrationWaitlistMoveUp.html';
308
                $subject = $settings['notification']['registrationWaitlistMoveUp']['userSubject'] ?? '';
309
                break;
310
            case MessageType::CUSTOM_NOTIFICATION:
311
                $customNotificationSettings = $settings['notification']['customNotifications'] ?? [];
312
                $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

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