initializeSaveRegistrationAction()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 13
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 19
rs 9.8333
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\Controller;
13
14
use DateInterval;
15
use DateTime;
16
use DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand;
17
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
18
use DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand;
19
use DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand;
20
use DERHANSEN\SfEventMgt\Domain\Model\Event;
21
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
22
use DERHANSEN\SfEventMgt\Event\AfterRegistrationCancelledEvent;
0 ignored issues
show
Bug introduced by
The type DERHANSEN\SfEventMgt\Eve...istrationCancelledEvent 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...
23
use DERHANSEN\SfEventMgt\Event\AfterRegistrationConfirmedEvent;
0 ignored issues
show
Bug introduced by
The type DERHANSEN\SfEventMgt\Eve...istrationConfirmedEvent 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...
24
use DERHANSEN\SfEventMgt\Event\AfterRegistrationSavedEvent;
0 ignored issues
show
Bug introduced by
The type DERHANSEN\SfEventMgt\Eve...rRegistrationSavedEvent 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...
25
use DERHANSEN\SfEventMgt\Event\ModifyCalendarViewVariablesEvent;
26
use DERHANSEN\SfEventMgt\Event\ModifyCancelRegistrationViewVariablesEvent;
27
use DERHANSEN\SfEventMgt\Event\ModifyConfirmRegistrationViewVariablesEvent;
28
use DERHANSEN\SfEventMgt\Event\ModifyCreateDependingRegistrationsEvent;
29
use DERHANSEN\SfEventMgt\Event\ModifyDetailViewVariablesEvent;
30
use DERHANSEN\SfEventMgt\Event\ModifyListViewVariablesEvent;
31
use DERHANSEN\SfEventMgt\Event\ModifyRegistrationViewVariablesEvent;
32
use DERHANSEN\SfEventMgt\Event\ModifySearchViewVariablesEvent;
33
use DERHANSEN\SfEventMgt\Event\ProcessCancelDependingRegistrationsEvent;
34
use DERHANSEN\SfEventMgt\Event\ProcessRedirectToPaymentEvent;
35
use DERHANSEN\SfEventMgt\Event\WaitlistMoveUpEvent;
36
use DERHANSEN\SfEventMgt\Exception;
37
use DERHANSEN\SfEventMgt\Security\HashScope;
38
use DERHANSEN\SfEventMgt\Service\EventCacheService;
39
use DERHANSEN\SfEventMgt\Service\EventEvaluationService;
40
use DERHANSEN\SfEventMgt\Utility\MessageType;
41
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
42
use Psr\Http\Message\ResponseInterface;
43
use TYPO3\CMS\Core\Cache\CacheTag;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Cache\CacheTag 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...
44
use TYPO3\CMS\Core\Http\PropagateResponseException;
45
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
46
use TYPO3\CMS\Core\Utility\ArrayUtility;
47
use TYPO3\CMS\Core\Utility\GeneralUtility;
48
use TYPO3\CMS\Core\View\ViewFactoryData;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\View\ViewFactoryData 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...
49
use TYPO3\CMS\Core\View\ViewFactoryInterface;
50
use TYPO3\CMS\Extbase\Annotation as Extbase;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Annotation 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...
51
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Persis...eric\PersistenceManager 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...
52
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Proper...erter\DateTimeConverter 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...
53
use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Proper...rsistentObjectConverter 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...
54
use TYPO3\CMS\Frontend\Controller\ErrorController;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Frontend\Controller\ErrorController 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...
55
56
class EventController extends AbstractController
57
{
58
    protected EventCacheService $eventCacheService;
59
    protected ViewFactoryInterface $viewFactory;
60
    protected EventEvaluationService $eventEvaluationService;
61
62
    public function injectEventCacheService(EventCacheService $cacheService): void
63
    {
64
        $this->eventCacheService = $cacheService;
65
    }
66
67
    public function injectViewFactoryInterface(ViewFactoryInterface $viewFactory): void
68
    {
69
        $this->viewFactory = $viewFactory;
70
    }
71
72
    public function injectEventEvaluationService(EventEvaluationService $eventEvaluationService): void
73
    {
74
        $this->eventEvaluationService = $eventEvaluationService;
75
    }
76
77
    /**
78
     * Assign contentObjectData and pageData view
79
     */
80
    protected function initializeView(): void
81
    {
82
        $this->view->assign('contentObjectData', $this->request->getAttribute('currentContentObject')->data ?? null);
83
        $this->view->assign('pageData', $this->getFrontendPageInformation()->getPageRecord());
84
    }
85
86
    /**
87
     * Initializes the current action
88
     */
89
    public function initializeAction(): void
90
    {
91
        static $cacheTagsSet = false;
92
93
        if (!$cacheTagsSet) {
94
            $this->request->getAttribute('frontend.cache.collector')->addCacheTags(new CacheTag('tx_sfeventmgt'));
95
            $cacheTagsSet = true;
96
        }
97
    }
98
99
    /**
100
     * Initialize list action and set format
101
     */
102
    public function initializeListAction(): void
103
    {
104
        if (isset($this->settings['list']['format'])) {
105
            $this->request = $this->request->withFormat($this->settings['list']['format']);
0 ignored issues
show
Bug Best Practice introduced by
The property request does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
106
        }
107
    }
108
109
    /**
110
     * List view
111
     */
112
    public function listAction(array $overwriteDemand = []): ResponseInterface
113
    {
114
        $eventDemand = EventDemand::createFromSettings($this->settings);
115
        $foreignRecordDemand = ForeignRecordDemand::createFromSettings($this->settings);
116
        $categoryDemand = CategoryDemand::createFromSettings($this->settings);
117
        if ($this->isOverwriteDemand($overwriteDemand)) {
118
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
119
        }
120
        $events = $this->eventRepository->findDemanded($eventDemand);
121
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
122
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
123
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
124
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
125
126
        $modifyListViewVariablesEvent = new ModifyListViewVariablesEvent(
127
            [
128
                'events' => $events,
129
                'pagination' => $this->getPagination($events, $this->settings['pagination'] ?? []),
130
                'categories' => $categories,
131
                'locations' => $locations,
132
                'organisators' => $organisators,
133
                'speakers' => $speakers,
134
                'overwriteDemand' => $overwriteDemand,
135
                'eventDemand' => $eventDemand,
136
                'settings' => $this->settings,
137
            ],
138
            $this,
139
            $this->request
140
        );
141
        $this->eventDispatcher->dispatch($modifyListViewVariablesEvent);
142
        $variables = $modifyListViewVariablesEvent->getVariables();
143
        $this->view->assignMultiple($variables);
144
145
        $cacheDataCollector = $this->request->getAttribute('frontend.cache.collector');
146
        $this->eventCacheService->addPageCacheTagsByEventDemandObject($cacheDataCollector, $eventDemand);
147
148
        return $this->htmlResponse();
149
    }
150
151
    /**
152
     * Calendar view
153
     */
154
    public function calendarAction(array $overwriteDemand = []): ResponseInterface
155
    {
156
        $eventDemand = EventDemand::createFromSettings($this->settings);
157
        $foreignRecordDemand = ForeignRecordDemand::createFromSettings($this->settings);
158
        $categoryDemand = CategoryDemand::createFromSettings($this->settings);
159
        if ($this->isOverwriteDemand($overwriteDemand)) {
160
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
161
        }
162
163
        // Set month/year to demand if not given
164
        if (!$eventDemand->getMonth()) {
165
            $currentMonth = (int)date('n');
166
            $eventDemand->setMonth($currentMonth);
167
        } else {
168
            $currentMonth = $eventDemand->getMonth();
169
        }
170
        if (!$eventDemand->getYear()) {
171
            $currentYear = (int)date('Y');
172
            $eventDemand->setYear($currentYear);
173
        } else {
174
            $currentYear = $eventDemand->getYear();
175
        }
176
177
        // If a weeknumber is given in overwriteDemand['week'], we overwrite the current month
178
        if ($overwriteDemand['week'] ?? false) {
179
            $firstDayOfWeek = (new DateTime())->setISODate($currentYear, (int)$overwriteDemand['week']);
180
            $currentMonth = (int)$firstDayOfWeek->format('m');
181
            $eventDemand->setMonth($currentMonth);
182
        } else {
183
            $firstDayOfWeek = (new DateTime())->setISODate($currentYear, (int)date('W'));
184
        }
185
186
        // Set demand from calendar date range instead of month / year
187
        if ((bool)($this->settings['calendar']['includeEventsForEveryDayOfAllCalendarWeeks'] ?? false)) {
188
            $eventDemand = $this->changeEventDemandToFullMonthDateRange($eventDemand);
189
        }
190
191
        $events = $this->eventRepository->findDemanded($eventDemand);
192
        $weeks = $this->calendarService->getCalendarArray(
193
            $currentMonth,
194
            $currentYear,
195
            strtotime('today midnight'),
196
            (int)($this->settings['calendar']['firstDayOfWeek'] ?? 1),
197
            $events
198
        );
199
200
        $modifyCalendarViewVariablesEvent = new ModifyCalendarViewVariablesEvent(
201
            [
202
                'events' => $events,
203
                'weeks' => $weeks,
204
                'categories' => $this->categoryRepository->findDemanded($categoryDemand),
205
                'locations' => $this->locationRepository->findDemanded($foreignRecordDemand),
206
                'organisators' => $this->organisatorRepository->findDemanded($foreignRecordDemand),
207
                'eventDemand' => $eventDemand,
208
                'overwriteDemand' => $overwriteDemand,
209
                'currentPageId' => $this->getFrontendPageInformation()->getId(),
210
                'firstDayOfMonth' => DateTime::createFromFormat(
211
                    'd.m.Y',
212
                    sprintf('1.%s.%s', $currentMonth, $currentYear)
213
                ),
214
                'previousMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '-1 month'),
215
                'nextMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '+1 month'),
216
                'weekConfig' => $this->calendarService->getWeekConfig($firstDayOfWeek),
217
                'settings' => $this->settings,
218
            ],
219
            $this,
220
            $this->request
221
        );
222
        $this->eventDispatcher->dispatch($modifyCalendarViewVariablesEvent);
223
        $variables = $modifyCalendarViewVariablesEvent->getVariables();
224
225
        $this->view->assignMultiple($variables);
226
        return $this->htmlResponse();
227
    }
228
229
    /**
230
     * Changes the given event demand object to select a date range for a calendar month including days of the previous
231
     * month for the first week and they days for the next month for the last week
232
     */
233
    protected function changeEventDemandToFullMonthDateRange(EventDemand $eventDemand): EventDemand
234
    {
235
        $calendarDateRange = $this->calendarService->getCalendarDateRange(
236
            $eventDemand->getMonth(),
237
            $eventDemand->getYear(),
238
            (int)($this->settings['calendar']['firstDayOfWeek'] ?? 0)
239
        );
240
241
        $eventDemand->setMonth(0);
242
        $eventDemand->setYear(0);
243
244
        $startDate = new DateTime();
245
        $startDate->setTimestamp($calendarDateRange['firstDayOfCalendar']);
246
        $endDate = new DateTime();
247
        $endDate->setTimestamp($calendarDateRange['lastDayOfCalendar']);
248
        $endDate->setTime(23, 59, 59);
249
250
        $searchDemand = GeneralUtility::makeInstance(SearchDemand::class);
251
        $searchDemand->setStartDate($startDate);
252
        $searchDemand->setEndDate($endDate);
253
        $eventDemand->setSearchDemand($searchDemand);
254
255
        return $eventDemand;
256
    }
257
258
    /**
259
     * Detail view for an event
260
     */
261
    public function detailAction(?Event $event = null): ResponseInterface
262
    {
263
        $event = $this->eventEvaluationService->evaluateForDetailAction($this->request, $this->settings, $event);
264
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
265
            return $this->handleEventNotFoundError($this->settings);
266
        }
267
268
        $modifyDetailViewVariablesEvent = new ModifyDetailViewVariablesEvent(
269
            [
270
                'event' => $event,
271
                'settings' => $this->settings,
272
            ],
273
            $this,
274
            $this->request
275
        );
276
        $this->eventDispatcher->dispatch($modifyDetailViewVariablesEvent);
277
        $variables = $modifyDetailViewVariablesEvent->getVariables();
278
279
        $this->view->assignMultiple($variables);
280
        if ($event !== null) {
281
            $cacheDataCollector = $this->request->getAttribute('frontend.cache.collector');
282
            $this->eventCacheService->addCacheTagsByEventRecords($cacheDataCollector, [$event]);
283
        }
284
285
        return $this->htmlResponse();
286
    }
287
288
    /**
289
     * Error handling if event is not found
290
     */
291
    protected function handleEventNotFoundError(array $settings): ResponseInterface
292
    {
293
        if (empty($settings['event']['errorHandling'])) {
294
            throw new Exception('Event errorHandling not configured. Please check settings.event.errorHandling', 1671205677);
295
        }
296
297
        $configuration = GeneralUtility::trimExplode(',', $settings['event']['errorHandling'], true);
298
299
        switch ($configuration[0]) {
300
            case 'redirectToListView':
301
                $listPid = (int)($settings['listPid'] ?? 0) > 0 ? (int)$settings['listPid'] : 1;
302
                return $this->redirect('list', null, null, null, $listPid);
303
            case 'pageNotFoundHandler':
304
                $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
305
                    $this->request,
306
                    'Event not found.'
307
                );
308
                throw new PropagateResponseException($response, 1631261423);
309
            case 'showStandaloneTemplate':
310
            default:
311
                $status = (int)($configuration[2] ?? 200);
312
                $viewFactoryData = new ViewFactoryData(
313
                    templatePathAndFilename: GeneralUtility::getFileAbsFileName($configuration[1]),
314
                    request: $this->request,
315
                );
316
                $view = $this->viewFactory->create($viewFactoryData);
317
318
                $response = $this->responseFactory->createResponse()
319
                    ->withStatus($status)
320
                    ->withHeader('Content-Type', 'text/html; charset=utf-8');
321
                $response->getBody()->write($view->render());
322
                return $response;
323
        }
324
    }
325
326
    /**
327
     * Initiates the iCalendar download for the given event
328
     *
329
     * @return mixed
330
     */
331
    public function icalDownloadAction(?Event $event = null)
332
    {
333
        $event = $this->eventEvaluationService->evaluateForIcalDownloadAction($this->request, $this->settings, $event);
334
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
335
            return $this->handleEventNotFoundError($this->settings);
336
        }
337
        $this->icalendarService->downloadiCalendarFile($this->request, $event);
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...downloadiCalendarFile() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

337
        $this->icalendarService->downloadiCalendarFile($this->request, /** @scrutinizer ignore-type */ $event);
Loading history...
338
        exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
339
    }
340
341
    /**
342
     * Registration view for an event
343
     */
344
    public function registrationAction(?Event $event = null): ResponseInterface
345
    {
346
        $event = $this->eventEvaluationService->evaluateForRegistrationAction($this->request, $this->settings, $event);
347
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
348
            return $this->handleEventNotFoundError($this->settings);
349
        }
350
        if ($event->getRestrictPaymentMethods()) {
351
            $paymentMethods = $this->paymentService->getRestrictedPaymentMethods($event);
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...trictedPaymentMethods() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

351
            $paymentMethods = $this->paymentService->getRestrictedPaymentMethods(/** @scrutinizer ignore-type */ $event);
Loading history...
352
        } else {
353
            $paymentMethods = $this->paymentService->getPaymentMethods();
354
        }
355
356
        $modifyRegistrationViewVariablesEvent = new ModifyRegistrationViewVariablesEvent(
357
            [
358
                'event' => $event,
359
                'paymentMethods' => $paymentMethods,
360
                'settings' => $this->settings,
361
            ],
362
            $this,
363
            $this->request
364
        );
365
        $this->eventDispatcher->dispatch($modifyRegistrationViewVariablesEvent);
366
        $variables = $modifyRegistrationViewVariablesEvent->getVariables();
367
        $this->view->assignMultiple($variables);
368
369
        return $this->htmlResponse();
370
    }
371
372
    /**
373
     * Removes all possible spamcheck fields (which do not belong to the domain model) from arguments.
374
     */
375
    protected function removePossibleSpamCheckFieldsFromArguments(): void
376
    {
377
        $arguments = $this->request->getArguments();
378
        if (!isset($arguments['event'])) {
379
            return;
380
        }
381
382
        // Remove a possible honeypot field
383
        $honeypotField = 'hp' . (int)$arguments['event'];
384
        if (isset($arguments['registration'][$honeypotField])) {
385
            unset($arguments['registration'][$honeypotField]);
386
        }
387
388
        // Remove a possible challenge/response field
389
        if (isset($arguments['registration']['cr-response'])) {
390
            unset($arguments['registration']['cr-response']);
391
        }
392
393
        $this->request = $this->request->withArguments($arguments);
0 ignored issues
show
Bug Best Practice introduced by
The property request does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
394
    }
395
396
    /**
397
     * Processes incoming registrations fields and adds field values to arguments
398
     */
399
    protected function setRegistrationFieldValuesToArguments(): void
400
    {
401
        $arguments = $this->request->getArguments();
402
        if (!isset($arguments['event'])) {
403
            return;
404
        }
405
406
        /** @var Event $event */
407
        $event = $this->eventRepository->findByUid((int)$this->request->getArgument('event'));
408
        if (!is_a($event, Event::class)) {
409
            return;
410
        }
411
412
        $registrationMvcArgument = $this->arguments->getArgument('registration');
413
        $propertyMapping = $registrationMvcArgument->getPropertyMappingConfiguration();
414
        $propertyMapping->allowProperties('fieldValues');
415
        $propertyMapping->allowCreationForSubProperty('fieldValues');
416
        $propertyMapping->allowModificationForSubProperty('fieldValues');
417
418
        // Set event to registration (required for validation)
419
        $propertyMapping->allowProperties('event');
420
        $propertyMapping->allowCreationForSubProperty('event');
421
        $propertyMapping->allowModificationForSubProperty('event');
422
        $arguments['registration']['event'] = (int)$this->request->getArgument('event');
423
424
        if (count($event->getRegistrationFieldsUids()) === 0) {
425
            // Set arguments to request, so event is set for event
426
            $this->request = $this->request->withArguments($arguments);
0 ignored issues
show
Bug Best Practice introduced by
The property request does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
427
            return;
428
        }
429
430
        // allow creation of new objects (for validation)
431
        $propertyMapping->setTypeConverterOptions(
432
            PersistentObjectConverter::class,
433
            [
434
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true,
435
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => true,
436
            ]
437
        );
438
439
        $index = 0;
440
        foreach ((array)($arguments['registration']['fields'] ?? []) as $fieldUid => $value) {
441
            // Only accept registration fields of the current event
442
            if (!in_array((int)$fieldUid, $event->getRegistrationFieldsUids(), true)) {
443
                continue;
444
            }
445
446
            // allow subvalues in new property mapper
447
            $propertyMapping->forProperty('fieldValues')->allowProperties($index);
448
            $propertyMapping->forProperty('fieldValues.' . $index)->allowAllProperties();
449
            $propertyMapping->allowCreationForSubProperty('fieldValues.' . $index);
450
            $propertyMapping->allowModificationForSubProperty('fieldValues.' . $index);
451
452
            if (is_array($value)) {
453
                if (empty($value)) {
454
                    $value = '';
455
                } else {
456
                    $value = json_encode($value);
457
                }
458
            }
459
460
            /** @var Registration\Field $field */
461
            $field = $this->fieldRepository->findByUid((int)$fieldUid);
462
463
            $arguments['registration']['fieldValues'][$index] = [
464
                'pid' => $field->getPid(),
465
                'value' => $value,
466
                'field' => (string)$fieldUid,
467
                'valueType' => $field->getValueType(),
468
            ];
469
470
            $index++;
471
        }
472
473
        // Remove temporary "fields" field
474
        if (isset($arguments['registration']['fields'])) {
475
            $arguments = ArrayUtility::removeByPath($arguments, 'registration/fields');
476
        }
477
        $this->request = $this->request->withArguments($arguments);
478
    }
479
480
    /**
481
     * Initialize arguments for saveRegistrationAction and ensures, action is only called via POST
482
     */
483
    public function initializeSaveRegistrationAction(): void
484
    {
485
        if ($this->request->getMethod() !== 'POST') {
486
            $response = GeneralUtility::makeInstance(ErrorController::class)->accessDeniedAction(
487
                $this->request,
488
                'HTTP method is not allowed'
489
            );
490
            throw new PropagateResponseException($response, 1726573183);
491
        }
492
493
        $this->arguments->getArgument('registration')
494
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
495
            ->setTypeConverterOption(
496
                DateTimeConverter::class,
497
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
498
                $this->settings['registration']['formatDateOfBirth'] ?? 'd.m.Y'
499
            );
500
        $this->removePossibleSpamCheckFieldsFromArguments();
501
        $this->setRegistrationFieldValuesToArguments();
502
    }
503
504
    /**
505
     * Saves the registration
506
     *
507
     * @Extbase\Validate("DERHANSEN\SfEventMgt\Validation\Validator\RegistrationFieldValidator", param="registration")
508
     * @Extbase\Validate("DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator", param="registration")
509
     */
510
    public function saveRegistrationAction(Registration $registration, Event $event): ResponseInterface
511
    {
512
        $event = $this->eventEvaluationService->evaluateForSaveRegistrationAction(
513
            $this->request,
514
            $this->settings,
515
            $event
516
        );
517
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
518
            return $this->handleEventNotFoundError($this->settings);
519
        }
520
        $autoConfirmation = (bool)($this->settings['registration']['autoConfirmation'] ?? false) ||
521
            $event->getEnableAutoconfirm();
522
        [$success, $result] = $this->registrationService->checkRegistrationSuccess($event, $registration);
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...ckRegistrationSuccess() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

522
        [$success, $result] = $this->registrationService->checkRegistrationSuccess(/** @scrutinizer ignore-type */ $event, $registration);
Loading history...
523
524
        // Save registration if no errors
525
        $registrationUid = 0;
526
        if ($success) {
527
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
528
                $event,
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...sWaitlistRegistration() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

528
                /** @scrutinizer ignore-type */ $event,
Loading history...
529
                $registration->getAmountOfRegistrations()
530
            );
531
            $linkValidity = (int)($this->settings['confirmation']['linkValidity'] ?? 3600);
532
            if ($linkValidity === 0) {
533
                // Use 3600 seconds as default value if not set or zero
534
                $linkValidity = 3600;
535
            }
536
            $confirmationUntil = new DateTime();
537
            $confirmationUntil->add(new DateInterval('PT' . $linkValidity . 'S'));
538
            $price = $this->registrationService->evaluateRegistrationPrice($event, $registration, $this->request);
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...uateRegistrationPrice() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

538
            $price = $this->registrationService->evaluateRegistrationPrice(/** @scrutinizer ignore-type */ $event, $registration, $this->request);
Loading history...
539
540
            $registration->setEvent($event);
541
            $registration->setPid($event->getPid());
542
            $registration->setRegistrationDate(new DateTime());
543
            $registration->setConfirmationUntil($confirmationUntil);
544
            $registration->setLanguage($this->getCurrentLanguageCode());
545
            $registration->setFeUser($this->registrationService->getCurrentFeUserObject());
546
            $registration->setWaitlist($isWaitlistRegistration);
547
            $registration->setPrice($price);
548
549
            $this->registrationRepository->add($registration);
550
551
            // Persist registration, so we have an UID
552
            $this->persistAll();
553
            $registrationUid = $registration->getUid();
554
555
            if ($isWaitlistRegistration) {
556
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
557
            } else {
558
                $messageType = MessageType::REGISTRATION_NEW;
559
            }
560
561
            $this->eventDispatcher->dispatch(new AfterRegistrationSavedEvent($registration, $this, $this->request));
562
563
            // Send notifications to user and admin if confirmation link should be sent
564
            if (!$autoConfirmation) {
565
                $this->notificationService->sendUserMessage(
566
                    $this->request,
567
                    $event,
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...vice::sendUserMessage() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

567
                    /** @scrutinizer ignore-type */ $event,
Loading history...
568
                    $registration,
569
                    $this->settings,
570
                    $messageType
571
                );
572
                $this->notificationService->sendAdminMessage(
573
                    $this->request,
574
                    $event,
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...ice::sendAdminMessage() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

574
                    /** @scrutinizer ignore-type */ $event,
Loading history...
575
                    $registration,
576
                    $this->settings,
577
                    $messageType
578
                );
579
            }
580
581
            // Create given amount of registrations if necessary
582
            $modifyCreateDependingRegistrationsEvent = new ModifyCreateDependingRegistrationsEvent(
583
                $registration,
584
                ($registration->getAmountOfRegistrations() > 1),
585
                $this,
586
                $this->request
587
            );
588
            $this->eventDispatcher->dispatch($modifyCreateDependingRegistrationsEvent);
589
            $createDependingRegistrations = $modifyCreateDependingRegistrationsEvent->getCreateDependingRegistrations();
590
            if ($createDependingRegistrations) {
591
                $this->registrationService->createDependingRegistrations($registration);
592
            }
593
594
            // Flush page cache for event, since new registration has been added
595
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
596
        }
597
598
        if ($autoConfirmation && $success) {
599
            return $this->redirect(
600
                'confirmRegistration',
601
                null,
602
                null,
603
                [
604
                    'reguid' => $registration->getUid(),
605
                    'hmac' => $this->hashService->hmac(
606
                        'reg-' . $registration->getUid(),
607
                        HashScope::RegistrationUid->value
608
                    ),
609
                ]
610
            );
611
        }
612
613
        return $this->redirect(
614
            'saveRegistrationResult',
615
            null,
616
            null,
617
            [
618
                'result' => $result,
619
                'eventuid' => $event->getUid(),
620
                'reguid' => $registrationUid,
621
                'hmac' => $this->hashService->hmac(
622
                    'event-' . $event->getUid() . '-reg-' . $registrationUid,
623
                    HashScope::SaveRegistrationResult->value
624
                ),
625
            ]
626
        );
627
    }
628
629
    /**
630
     * Shows the result of the saveRegistrationAction
631
     */
632
    public function saveRegistrationResultAction(int $result, int $eventuid, string $hmac): ResponseInterface
633
    {
634
        $reguid = $this->request->hasArgument('reguid') ? (int)$this->request->getArgument('reguid') : 0;
635
636
        $event = null;
637
        $registration = null;
638
        $failed = true;
639
640
        switch ($result) {
641
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
642
                $messageKey = 'event.message.registrationsuccessful';
643
                $titleKey = 'registrationResult.title.successful';
644
                $failed = false;
645
                break;
646
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
647
                $messageKey = 'event.message.registrationwaitlistsuccessful';
648
                $titleKey = 'registrationWaitlistResult.title.successful';
649
                $failed = false;
650
                break;
651
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
652
                $messageKey = 'event.message.registrationfailedeventexpired';
653
                $titleKey = 'registrationResult.title.failed';
654
                break;
655
            case RegistrationResult::REGISTRATION_FAILED_EVENT_ENDED:
656
                $messageKey = 'event.message.registrationfailedeventended';
657
                $titleKey = 'registrationResult.title.failed';
658
                break;
659
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
660
                $messageKey = 'event.message.registrationfailedmaxparticipants';
661
                $titleKey = 'registrationResult.title.failed';
662
                break;
663
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
664
                $messageKey = 'event.message.registrationfailednotenabled';
665
                $titleKey = 'registrationResult.title.failed';
666
                break;
667
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
668
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
669
                $titleKey = 'registrationResult.title.failed';
670
                break;
671
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
672
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
673
                $titleKey = 'registrationResult.title.failed';
674
                break;
675
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
676
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
677
                $titleKey = 'registrationResult.title.failed';
678
                break;
679
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
680
                $messageKey = 'event.message.registrationfailedemailnotunique';
681
                $titleKey = 'registrationResult.title.failed';
682
                break;
683
            default:
684
                $messageKey = '';
685
                $titleKey = '';
686
        }
687
688
        $isValidHmac = $this->hashService->validateHmac(
689
            'event-' . $eventuid . '-reg-' . $reguid,
690
            HashScope::SaveRegistrationResult->value,
691
            $hmac
692
        );
693
        if (!$isValidHmac) {
694
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
695
            $titleKey = 'registrationResult.title.failed';
696
        } else {
697
            $event = $this->eventRepository->findByUid($eventuid);
698
            $registration = $this->registrationRepository->findByUid($reguid);
699
        }
700
701
        $this->view->assignMultiple([
702
            'messageKey' => $messageKey,
703
            'titleKey' => $titleKey,
704
            'event' => $event,
705
            'registration' => $registration,
706
            'result' => $result,
707
            'failed' => $failed,
708
        ]);
709
710
        return $this->htmlResponse();
711
    }
712
713
    /**
714
     * Shows the verify confirmation registration view, where the user has to submit a form to finally
715
     * confirm the registration
716
     */
717
    public function verifyConfirmRegistrationAction(int $reguid, string $hmac): ResponseInterface
718
    {
719
        /* @var $registration Registration */
720
        [$failed, $registration, $messageKey, $titleKey] = $this->registrationService->checkConfirmRegistration(
721
            $reguid,
722
            $hmac
723
        );
724
725
        $variables = [
726
            'reguid' => $reguid,
727
            'hmac' => $hmac,
728
            'confirmationPossible' => $registration && !$registration->getConfirmed(),
729
            'failed' => $failed,
730
            'messageKey' => $messageKey,
731
            'titleKey' => $titleKey,
732
            'event' => $registration?->getEvent(),
733
            'registration' => $registration,
734
            'settings' => $this->settings,
735
        ];
736
737
        $this->view->assignMultiple($variables);
738
739
        return $this->htmlResponse();
740
    }
741
742
    /**
743
     * Confirms the registration if possible and sends emails to admin and user
744
     */
745
    public function confirmRegistrationAction(int $reguid, string $hmac): ResponseInterface
746
    {
747
        $event = null;
748
749
        /* @var $registration Registration */
750
        [$failed, $registration, $messageKey, $titleKey] = $this->registrationService->checkConfirmRegistration(
751
            $reguid,
752
            $hmac
753
        );
754
755
        if ($failed === false) {
756
            $registration->setConfirmed(true);
757
            $event = $registration->getEvent();
758
            $this->registrationRepository->update($registration);
759
760
            $this->eventDispatcher->dispatch(new AfterRegistrationConfirmedEvent($registration, $this, $this->request));
761
762
            $messageType = MessageType::REGISTRATION_CONFIRMED;
763
            if ($registration->getWaitlist()) {
764
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
765
            }
766
767
            // Send notifications to user and admin
768
            $this->notificationService->sendUserMessage(
769
                $this->request,
770
                $registration->getEvent(),
0 ignored issues
show
Bug introduced by
It seems like $registration->getEvent() can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...vice::sendUserMessage() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

770
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
771
                $registration,
772
                $this->settings,
773
                $messageType
774
            );
775
            $this->notificationService->sendAdminMessage(
776
                $this->request,
777
                $registration->getEvent(),
0 ignored issues
show
Bug introduced by
It seems like $registration->getEvent() can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...ice::sendAdminMessage() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

777
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
778
                $registration,
779
                $this->settings,
780
                $messageType
781
            );
782
783
            // Confirm registrations depending on main registration if necessary
784
            if ($registration->getAmountOfRegistrations() > 1) {
785
                $this->registrationService->confirmDependingRegistrations($registration);
786
            }
787
        }
788
789
        // Redirect to payment provider if payment/redirect is enabled.
790
        // Skip if the registration is a waitlist registration, since it is not sure, if the user will participate.
791
        $paymentPid = (int)($this->settings['paymentPid'] ?? 0);
792
        $paymentRedirectResponse = null;
793
        $processRedirect = !$failed &&
794
            $paymentPid > 0 &&
795
            $registration &&
796
            !$registration->getWaitlist() &&
797
            $this->registrationService->redirectPaymentEnabled($registration);
798
        if ($processRedirect) {
799
            $paymentRedirectResponse = $this->getRedirectToPaymentResponse($paymentPid, $registration);
800
        }
801
802
        if ($paymentRedirectResponse instanceof ResponseInterface) {
803
            return $paymentRedirectResponse;
804
        }
805
806
        $modifyConfirmRegistrationViewVariablesEvent = new ModifyConfirmRegistrationViewVariablesEvent(
807
            [
808
                'failed' => $failed,
809
                'messageKey' => $messageKey,
810
                'titleKey' => $titleKey,
811
                'event' => $event,
812
                'registration' => $registration,
813
                'settings' => $this->settings,
814
            ],
815
            $this,
816
            $this->request
817
        );
818
        $this->eventDispatcher->dispatch($modifyConfirmRegistrationViewVariablesEvent);
819
        $variables = $modifyConfirmRegistrationViewVariablesEvent->getVariables();
820
        $this->view->assignMultiple($variables);
821
822
        return $this->htmlResponse();
823
    }
824
825
    /**
826
     * Returns a response object to the given payment PID. Extension authors can use ProcessRedirectToPaymentEvent
827
     * PSR-14 event to intercept the redirect response.
828
     */
829
    private function getRedirectToPaymentResponse(int $paymentPid, Registration $registration): ?ResponseInterface
830
    {
831
        $processRedirectToPaymentEvent = new ProcessRedirectToPaymentEvent($registration, $this, $this->request);
832
        $this->eventDispatcher->dispatch($processRedirectToPaymentEvent);
833
        if ($processRedirectToPaymentEvent->getProcessRedirect()) {
834
            $this->uriBuilder->reset()
835
                ->setTargetPageUid($paymentPid);
836
            $uri = $this->uriBuilder->uriFor(
837
                'redirect',
838
                [
839
                    'registration' => $registration,
840
                    'hmac' => $this->hashService->hmac(
841
                        'redirectAction-' . $registration->getUid(),
842
                        HashScope::PaymentAction->value
843
                    ),
844
                ],
845
                'Payment',
846
                'sfeventmgt',
847
                'Pipayment'
848
            );
849
            return $this->redirectToUri($uri);
850
        }
851
852
        return null;
853
    }
854
855
    /**
856
     * Shows the verify cancel registration view, where the user has to submit a form to finally cancel the registration
857
     */
858
    public function verifyCancelRegistrationAction(int $reguid, string $hmac): ResponseInterface
859
    {
860
        /* @var $registration Registration */
861
        [$failed, $registration, $messageKey, $titleKey] = $this->registrationService->checkCancelRegistration(
862
            $reguid,
863
            $hmac
864
        );
865
866
        $variables = [
867
            'reguid' => $reguid,
868
            'hmac' => $hmac,
869
            'cancellationPossible' => !$failed,
870
            'failed' => $failed,
871
            'messageKey' => $messageKey,
872
            'titleKey' => $titleKey,
873
            'event' => $registration?->getEvent(),
874
            'registration' => $registration,
875
            'settings' => $this->settings,
876
        ];
877
878
        $this->view->assignMultiple($variables);
879
880
        return $this->htmlResponse();
881
    }
882
883
    /**
884
     * Cancels the registration if possible and sends emails to admin and user
885
     */
886
    public function cancelRegistrationAction(int $reguid, string $hmac): ResponseInterface
887
    {
888
        $event = null;
889
890
        /* @var $registration Registration */
891
        [$failed, $registration, $messageKey, $titleKey] = $this->registrationService->checkCancelRegistration(
892
            $reguid,
893
            $hmac
894
        );
895
896
        if ($failed === false) {
897
            $event = $registration->getEvent();
898
899
            // Send notifications (must run before cancelling the registration)
900
            $this->notificationService->sendUserMessage(
901
                $this->request,
902
                $registration->getEvent(),
0 ignored issues
show
Bug introduced by
It seems like $registration->getEvent() can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...vice::sendUserMessage() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

902
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
903
                $registration,
904
                $this->settings,
905
                MessageType::REGISTRATION_CANCELLED
906
            );
907
            $this->notificationService->sendAdminMessage(
908
                $this->request,
909
                $registration->getEvent(),
0 ignored issues
show
Bug introduced by
It seems like $registration->getEvent() can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...ice::sendAdminMessage() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

909
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
910
                $registration,
911
                $this->settings,
912
                MessageType::REGISTRATION_CANCELLED
913
            );
914
915
            // First cancel depending registrations
916
            $processCancelDependingRegistrations = new ProcessCancelDependingRegistrationsEvent(
917
                $registration,
918
                $registration->getAmountOfRegistrations() > 1,
919
                $this->request
920
            );
921
            $this->eventDispatcher->dispatch($processCancelDependingRegistrations);
922
            if ($processCancelDependingRegistrations->getProcessCancellation()) {
923
                $this->registrationService->cancelDependingRegistrations($registration);
924
            }
925
926
            // Finally cancel registration
927
            $this->registrationRepository->remove($registration);
928
929
            // Persist changes, so following functions can work with $event properties (e.g. amount of registrations)
930
            $this->persistAll();
931
932
            $afterRegistrationCancelledEvent = new AfterRegistrationCancelledEvent(
933
                $registration,
934
                $this,
935
                $this->request
936
            );
937
            $this->eventDispatcher->dispatch($afterRegistrationCancelledEvent);
938
939
            // Dispatch event, so waitlist registrations can be moved up and default move up process can be stopped
940
            $waitlistMoveUpEvent = new WaitlistMoveUpEvent($event, $this, $this->request, true);
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Eve...eUpEvent::__construct() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

940
            $waitlistMoveUpEvent = new WaitlistMoveUpEvent(/** @scrutinizer ignore-type */ $event, $this, $this->request, true);
Loading history...
941
            $this->eventDispatcher->dispatch($waitlistMoveUpEvent);
942
943
            // Move up waitlist registrations if configured on event basis and if not disabled by $waitlistMoveUpEvent
944
            if ($waitlistMoveUpEvent->getProcessDefaultMoveUp()) {
945
                $this->registrationService->moveUpWaitlistRegistrations($this->request, $event, $this->settings);
0 ignored issues
show
Bug introduced by
It seems like $event can also be of type null; however, parameter $event of DERHANSEN\SfEventMgt\Ser...WaitlistRegistrations() does only seem to accept DERHANSEN\SfEventMgt\Domain\Model\Event, 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

945
                $this->registrationService->moveUpWaitlistRegistrations($this->request, /** @scrutinizer ignore-type */ $event, $this->settings);
Loading history...
946
            }
947
948
            // Flush page cache for event, since amount of registrations has changed
949
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
950
        }
951
952
        $modifyCancelRegistrationViewVariablesEvent = new ModifyCancelRegistrationViewVariablesEvent(
953
            [
954
                'failed' => $failed,
955
                'messageKey' => $messageKey,
956
                'titleKey' => $titleKey,
957
                'event' => $event,
958
                'settings' => $this->settings,
959
            ],
960
            $this,
961
            $this->request
962
        );
963
        $this->eventDispatcher->dispatch($modifyCancelRegistrationViewVariablesEvent);
964
        $variables = $modifyCancelRegistrationViewVariablesEvent->getVariables();
965
        $this->view->assignMultiple($variables);
966
967
        return $this->htmlResponse();
968
    }
969
970
    /**
971
     * Set date format for field startDate and endDate
972
     */
973
    public function initializeSearchAction(): void
974
    {
975
        if ($this->settings !== [] && ($this->settings['search']['dateFormat'] ?? false)) {
976
            $this->arguments->getArgument('searchDemand')
977
                ->getPropertyMappingConfiguration()->forProperty('startDate')
978
                ->setTypeConverterOption(
979
                    DateTimeConverter::class,
980
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
981
                    $this->settings['search']['dateFormat']
982
                );
983
            $this->arguments->getArgument('searchDemand')
984
                ->getPropertyMappingConfiguration()->forProperty('endDate')
985
                ->setTypeConverterOption(
986
                    DateTimeConverter::class,
987
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
988
                    $this->settings['search']['dateFormat']
989
                );
990
        }
991
        if ($this->arguments->hasArgument('searchDemand')) {
992
            $propertyMappingConfiguration = $this->arguments->getArgument('searchDemand')
993
                ->getPropertyMappingConfiguration();
994
            $propertyMappingConfiguration->allowAllProperties();
995
            $propertyMappingConfiguration->setTypeConverterOption(
996
                PersistentObjectConverter::class,
997
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED,
998
                true
999
            );
1000
        }
1001
    }
1002
1003
    /**
1004
     * Search view
1005
     */
1006
    public function searchAction(?SearchDemand $searchDemand = null, array $overwriteDemand = []): ResponseInterface
1007
    {
1008
        $eventDemand = EventDemand::createFromSettings($this->settings);
1009
        $eventDemand->setSearchDemand($searchDemand);
1010
        $foreignRecordDemand = ForeignRecordDemand::createFromSettings($this->settings);
1011
        $categoryDemand = CategoryDemand::createFromSettings($this->settings);
1012
1013
        if ($searchDemand !== null) {
1014
            $searchDemand->setFields($this->settings['search']['fields'] ?? '');
1015
1016
            $adjustTime = (bool)($this->settings['search']['adjustTime'] ?? false);
1017
            if ($adjustTime && $searchDemand->getStartDate() !== null) {
1018
                $searchDemand->getStartDate()->setTime(0, 0);
1019
            }
1020
1021
            if ($adjustTime && $searchDemand->getEndDate() !== null) {
1022
                $searchDemand->getEndDate()->setTime(23, 59, 59);
1023
            }
1024
        }
1025
1026
        if ($this->isOverwriteDemand($overwriteDemand)) {
1027
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
1028
        }
1029
1030
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
1031
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
1032
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
1033
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
1034
        $events = $this->eventRepository->findDemanded($eventDemand);
1035
1036
        $modifySearchViewVariablesEvent = new ModifySearchViewVariablesEvent(
1037
            [
1038
                'events' => $events,
1039
                'categories' => $categories,
1040
                'locations' => $locations,
1041
                'organisators' => $organisators,
1042
                'speakers' => $speakers,
1043
                'searchDemand' => $searchDemand,
1044
                'overwriteDemand' => $overwriteDemand,
1045
                'settings' => $this->settings,
1046
            ],
1047
            $this,
1048
            $this->request,
1049
        );
1050
        $this->eventDispatcher->dispatch($modifySearchViewVariablesEvent);
1051
        $variables = $modifySearchViewVariablesEvent->getVariables();
1052
        $this->view->assignMultiple($variables);
1053
1054
        return $this->htmlResponse();
1055
    }
1056
1057
    /**
1058
     * Returns if a demand object can be overwritten with the given overwriteDemand array
1059
     */
1060
    protected function isOverwriteDemand(array $overwriteDemand): bool
1061
    {
1062
        return (int)($this->settings['disableOverrideDemand'] ?? 0) !== 1 && $overwriteDemand !== [];
1063
    }
1064
1065
    /**
1066
     * Calls persistAll() of the persistenceManager
1067
     */
1068
    protected function persistAll(): void
1069
    {
1070
        GeneralUtility::makeInstance(PersistenceManager::class)->persistAll();
1071
    }
1072
1073
    /**
1074
     * Returns the language code of the current language
1075
     */
1076
    protected function getCurrentLanguageCode(): string
1077
    {
1078
        if ($this->request->getAttribute('language') instanceof SiteLanguage) {
1079
            /** @var SiteLanguage $siteLanguage */
1080
            $siteLanguage = $this->request->getAttribute('language');
1081
            return $siteLanguage->getLocale()->getLanguageCode();
1082
        }
1083
1084
        return '';
1085
    }
1086
}
1087