setRegistrationFieldValuesToArguments()   B
last analyzed

Complexity

Conditions 9
Paths 13

Size

Total Lines 79
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 45
nc 13
nop 0
dl 0
loc 79
rs 7.6444
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

330
        $this->icalendarService->downloadiCalendarFile(/** @scrutinizer ignore-type */ $event);
Loading history...
331
        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...
332
    }
333
334
    /**
335
     * Registration view for an event
336
     */
337
    public function registrationAction(?Event $event = null): ResponseInterface
338
    {
339
        $event = $this->evaluateSingleEventSetting($event);
340
        if (is_a($event, Event::class) && ($this->settings['registration']['checkPidOfEventRecord'] ?? false)) {
341
            $event = $this->checkPidOfEventRecord($event);
342
        }
343
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
344
            return $this->handleEventNotFoundError($this->settings);
345
        }
346
        if ($event->getRestrictPaymentMethods()) {
347
            $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

347
            $paymentMethods = $this->paymentService->getRestrictedPaymentMethods(/** @scrutinizer ignore-type */ $event);
Loading history...
348
        } else {
349
            $paymentMethods = $this->paymentService->getPaymentMethods();
350
        }
351
352
        $modifyRegistrationViewVariablesEvent = new ModifyRegistrationViewVariablesEvent(
353
            [
354
                'event' => $event,
355
                'paymentMethods' => $paymentMethods,
356
                'settings' => $this->settings,
357
            ],
358
            $this
359
        );
360
        $this->eventDispatcher->dispatch($modifyRegistrationViewVariablesEvent);
361
        $variables = $modifyRegistrationViewVariablesEvent->getVariables();
362
        $this->view->assignMultiple($variables);
363
364
        return $this->htmlResponse();
365
    }
366
367
    /**
368
     * Removes all possible spamcheck fields (which do not belong to the domain model) from arguments.
369
     */
370
    protected function removePossibleSpamCheckFieldsFromArguments(): void
371
    {
372
        $arguments = $this->request->getArguments();
373
        if (!isset($arguments['event'])) {
374
            return;
375
        }
376
377
        // Remove a possible honeypot field
378
        $honeypotField = 'hp' . (int)$arguments['event'];
379
        if (isset($arguments['registration'][$honeypotField])) {
380
            unset($arguments['registration'][$honeypotField]);
381
        }
382
383
        // Remove a possible challenge/response field
384
        if (isset($arguments['registration']['cr-response'])) {
385
            unset($arguments['registration']['cr-response']);
386
        }
387
388
        $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...
389
    }
390
391
    /**
392
     * Processes incoming registrations fields and adds field values to arguments
393
     */
394
    protected function setRegistrationFieldValuesToArguments(): void
395
    {
396
        $arguments = $this->request->getArguments();
397
        if (!isset($arguments['event'])) {
398
            return;
399
        }
400
401
        /** @var Event $event */
402
        $event = $this->eventRepository->findByUid((int)$this->request->getArgument('event'));
403
        if (!is_a($event, Event::class)) {
404
            return;
405
        }
406
407
        $registrationMvcArgument = $this->arguments->getArgument('registration');
408
        $propertyMapping = $registrationMvcArgument->getPropertyMappingConfiguration();
409
        $propertyMapping->allowProperties('fieldValues');
410
        $propertyMapping->allowCreationForSubProperty('fieldValues');
411
        $propertyMapping->allowModificationForSubProperty('fieldValues');
412
413
        // Set event to registration (required for validation)
414
        $propertyMapping->allowProperties('event');
415
        $propertyMapping->allowCreationForSubProperty('event');
416
        $propertyMapping->allowModificationForSubProperty('event');
417
        $arguments['registration']['event'] = (int)$this->request->getArgument('event');
418
419
        if (count($event->getRegistrationFieldsUids()) === 0) {
420
            // Set arguments to request, so event is set for event
421
            $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...
422
            return;
423
        }
424
425
        // allow creation of new objects (for validation)
426
        $propertyMapping->setTypeConverterOptions(
427
            PersistentObjectConverter::class,
428
            [
429
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true,
430
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => true,
431
            ]
432
        );
433
434
        $index = 0;
435
        foreach ((array)($arguments['registration']['fields'] ?? []) as $fieldUid => $value) {
436
            // Only accept registration fields of the current event
437
            if (!in_array((int)$fieldUid, $event->getRegistrationFieldsUids(), true)) {
438
                continue;
439
            }
440
441
            // allow subvalues in new property mapper
442
            $propertyMapping->forProperty('fieldValues')->allowProperties($index);
443
            $propertyMapping->forProperty('fieldValues.' . $index)->allowAllProperties();
444
            $propertyMapping->allowCreationForSubProperty('fieldValues.' . $index);
445
            $propertyMapping->allowModificationForSubProperty('fieldValues.' . $index);
446
447
            if (is_array($value)) {
448
                if (empty($value)) {
449
                    $value = '';
450
                } else {
451
                    $value = json_encode($value);
452
                }
453
            }
454
455
            /** @var Registration\Field $field */
456
            $field = $this->fieldRepository->findByUid((int)$fieldUid);
457
458
            $arguments['registration']['fieldValues'][$index] = [
459
                'pid' => $field->getPid(),
460
                'value' => $value,
461
                'field' => (string)$fieldUid,
462
                'valueType' => $field->getValueType(),
463
            ];
464
465
            $index++;
466
        }
467
468
        // Remove temporary "fields" field
469
        if (isset($arguments['registration']['fields'])) {
470
            $arguments = ArrayUtility::removeByPath($arguments, 'registration/fields');
471
        }
472
        $this->request = $this->request->withArguments($arguments);
473
    }
474
475
    /**
476
     * Set date format for field dateOfBirth
477
     */
478
    public function initializeSaveRegistrationAction(): void
479
    {
480
        $this->arguments->getArgument('registration')
481
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
482
            ->setTypeConverterOption(
483
                DateTimeConverter::class,
484
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
485
                $this->settings['registration']['formatDateOfBirth'] ?? 'd.m.Y'
486
            );
487
        $this->removePossibleSpamCheckFieldsFromArguments();
488
        $this->setRegistrationFieldValuesToArguments();
489
    }
490
491
    /**
492
     * Saves the registration
493
     *
494
     * @Extbase\Validate("DERHANSEN\SfEventMgt\Validation\Validator\RegistrationFieldValidator", param="registration")
495
     * @Extbase\Validate("DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator", param="registration")
496
     */
497
    public function saveRegistrationAction(Registration $registration, Event $event): ResponseInterface
498
    {
499
        if (is_a($event, Event::class) && ($this->settings['registration']['checkPidOfEventRecord'] ?? false)) {
500
            $event = $this->checkPidOfEventRecord($event);
501
        }
502
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
503
            return $this->handleEventNotFoundError($this->settings);
504
        }
505
        $autoConfirmation = (bool)($this->settings['registration']['autoConfirmation'] ?? false) ||
506
            $event->getEnableAutoconfirm();
507
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
508
        [$success, $result] = $this->registrationService->checkRegistrationSuccess($event, $registration, $result);
509
510
        // Save registration if no errors
511
        $registrationUid = 0;
512
        if ($success) {
513
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
514
                $event,
515
                $registration->getAmountOfRegistrations()
516
            );
517
            $linkValidity = (int)($this->settings['confirmation']['linkValidity'] ?? 3600);
518
            if ($linkValidity === 0) {
519
                // Use 3600 seconds as default value if not set or zero
520
                $linkValidity = 3600;
521
            }
522
            $confirmationUntil = new DateTime();
523
            $confirmationUntil->add(new DateInterval('PT' . $linkValidity . 'S'));
524
525
            $registration->setEvent($event);
526
            $registration->setPid($event->getPid());
527
            $registration->setRegistrationDate(new DateTime());
528
            $registration->setConfirmationUntil($confirmationUntil);
529
            $registration->setLanguage($this->getCurrentLanguageCode());
530
            $registration->setFeUser($this->registrationService->getCurrentFeUserObject());
531
            $registration->setWaitlist($isWaitlistRegistration);
532
            $this->registrationRepository->add($registration);
533
534
            // Persist registration, so we have an UID
535
            $this->persistAll();
536
            $registrationUid = $registration->getUid();
537
538
            if ($isWaitlistRegistration) {
539
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
540
            } else {
541
                $messageType = MessageType::REGISTRATION_NEW;
542
            }
543
544
            $this->eventDispatcher->dispatch(new AfterRegistrationSavedEvent($registration, $this));
545
546
            // Send notifications to user and admin if confirmation link should be sent
547
            if (!$autoConfirmation) {
548
                $this->notificationService->sendUserMessage(
549
                    $event,
550
                    $registration,
551
                    $this->settings,
552
                    $messageType
553
                );
554
                $this->notificationService->sendAdminMessage(
555
                    $event,
556
                    $registration,
557
                    $this->settings,
558
                    $messageType
559
                );
560
            }
561
562
            // Create given amount of registrations if necessary
563
            $modifyCreateDependingRegistrationsEvent = new ModifyCreateDependingRegistrationsEvent(
564
                $registration,
565
                ($registration->getAmountOfRegistrations() > 1),
566
                $this
567
            );
568
            $this->eventDispatcher->dispatch($modifyCreateDependingRegistrationsEvent);
569
            $createDependingRegistrations = $modifyCreateDependingRegistrationsEvent->getCreateDependingRegistrations();
570
            if ($createDependingRegistrations) {
571
                $this->registrationService->createDependingRegistrations($registration);
572
            }
573
574
            // Flush page cache for event, since new registration has been added
575
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
576
        }
577
578
        if ($autoConfirmation && $success) {
579
            return $this->redirect(
580
                'confirmRegistration',
581
                null,
582
                null,
583
                [
584
                    'reguid' => $registration->getUid(),
585
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid()),
586
                ]
587
            );
588
        }
589
590
        return $this->redirect(
591
            'saveRegistrationResult',
592
            null,
593
            null,
594
            [
595
                'result' => $result,
596
                'eventuid' => $event->getUid(),
597
                'reguid' => $registrationUid,
598
                'hmac' => $this->hashService->generateHmac('event-' . $event->getUid() . '-reg-' . $registrationUid),
599
            ]
600
        );
601
    }
602
603
    /**
604
     * Shows the result of the saveRegistrationAction
605
     */
606
    public function saveRegistrationResultAction(int $result, int $eventuid, string $hmac): ResponseInterface
607
    {
608
        $reguid = $this->request->hasArgument('reguid') ? (int)$this->request->getArgument('reguid') : 0;
609
610
        $event = null;
611
        $registration = null;
612
        $failed = true;
613
614
        switch ($result) {
615
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
616
                $messageKey = 'event.message.registrationsuccessful';
617
                $titleKey = 'registrationResult.title.successful';
618
                $failed = false;
619
                break;
620
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
621
                $messageKey = 'event.message.registrationwaitlistsuccessful';
622
                $titleKey = 'registrationWaitlistResult.title.successful';
623
                $failed = false;
624
                break;
625
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
626
                $messageKey = 'event.message.registrationfailedeventexpired';
627
                $titleKey = 'registrationResult.title.failed';
628
                break;
629
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
630
                $messageKey = 'event.message.registrationfailedmaxparticipants';
631
                $titleKey = 'registrationResult.title.failed';
632
                break;
633
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
634
                $messageKey = 'event.message.registrationfailednotenabled';
635
                $titleKey = 'registrationResult.title.failed';
636
                break;
637
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
638
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
639
                $titleKey = 'registrationResult.title.failed';
640
                break;
641
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
642
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
643
                $titleKey = 'registrationResult.title.failed';
644
                break;
645
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
646
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
647
                $titleKey = 'registrationResult.title.failed';
648
                break;
649
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
650
                $messageKey = 'event.message.registrationfailedemailnotunique';
651
                $titleKey = 'registrationResult.title.failed';
652
                break;
653
            default:
654
                $messageKey = '';
655
                $titleKey = '';
656
        }
657
658
        if (!$this->hashService->validateHmac('event-' . $eventuid . '-reg-' . $reguid, $hmac)) {
659
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
660
            $titleKey = 'registrationResult.title.failed';
661
        } else {
662
            $event = $this->eventRepository->findByUid($eventuid);
663
            $registration = $this->registrationRepository->findByUid($reguid);
664
        }
665
666
        $this->view->assignMultiple([
667
            'messageKey' => $messageKey,
668
            'titleKey' => $titleKey,
669
            'event' => $event,
670
            'registration' => $registration,
671
            'result' => $result,
672
            'failed' => $failed,
673
        ]);
674
675
        return $this->htmlResponse();
676
    }
677
678
    /**
679
     * Confirms the registration if possible and sends emails to admin and user
680
     */
681
    public function confirmRegistrationAction(int $reguid, string $hmac): ResponseInterface
682
    {
683
        $event = null;
684
685
        /* @var $registration Registration */
686
        [$failed, $registration, $messageKey, $titleKey] = $this->registrationService->checkConfirmRegistration(
687
            $reguid,
688
            $hmac
689
        );
690
691
        if ($failed === false) {
692
            $registration->setConfirmed(true);
693
            $event = $registration->getEvent();
694
            $this->registrationRepository->update($registration);
695
696
            $this->eventDispatcher->dispatch(new AfterRegistrationConfirmedEvent($registration, $this));
697
698
            $messageType = MessageType::REGISTRATION_CONFIRMED;
699
            if ($registration->getWaitlist()) {
700
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
701
            }
702
703
            // Send notifications to user and admin
704
            $this->notificationService->sendUserMessage(
705
                $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

705
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
706
                $registration,
707
                $this->settings,
708
                $messageType
709
            );
710
            $this->notificationService->sendAdminMessage(
711
                $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

711
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
712
                $registration,
713
                $this->settings,
714
                $messageType
715
            );
716
717
            // Confirm registrations depending on main registration if necessary
718
            if ($registration->getAmountOfRegistrations() > 1) {
719
                $this->registrationService->confirmDependingRegistrations($registration);
720
            }
721
        }
722
723
        // Redirect to payment provider if payment/redirect is enabled.
724
        // Skip if the registration is a waitlist registration, since it is not sure, if the user will participate.
725
        $paymentPid = (int)($this->settings['paymentPid'] ?? 0);
726
        $paymentRedirectResponse = null;
727
        $processRedirect = !$failed &&
728
            $paymentPid > 0 &&
729
            $registration &&
730
            !$registration->getWaitlist() &&
731
            $this->registrationService->redirectPaymentEnabled($registration);
732
        if ($processRedirect) {
733
            $paymentRedirectResponse = $this->getRedirectToPaymentResponse($paymentPid, $registration);
734
        }
735
736
        if ($paymentRedirectResponse instanceof ResponseInterface) {
737
            return $paymentRedirectResponse;
738
        }
739
740
        $modifyConfirmRegistrationViewVariablesEvent = new ModifyConfirmRegistrationViewVariablesEvent(
741
            [
742
                'failed' => $failed,
743
                'messageKey' => $messageKey,
744
                'titleKey' => $titleKey,
745
                'event' => $event,
746
                'registration' => $registration,
747
                'settings' => $this->settings,
748
            ],
749
            $this
750
        );
751
        $this->eventDispatcher->dispatch($modifyConfirmRegistrationViewVariablesEvent);
752
        $variables = $modifyConfirmRegistrationViewVariablesEvent->getVariables();
753
        $this->view->assignMultiple($variables);
754
755
        return $this->htmlResponse();
756
    }
757
758
    /**
759
     * Returns a response object to the given payment PID. Extension authors can use ProcessRedirectToPaymentEvent
760
     * PSR-14 event to intercept the redirect response.
761
     */
762
    private function getRedirectToPaymentResponse(int $paymentPid, Registration $registration): ?ResponseInterface
763
    {
764
        $processRedirectToPaymentEvent = new ProcessRedirectToPaymentEvent($registration, $this);
765
        $this->eventDispatcher->dispatch($processRedirectToPaymentEvent);
766
        if ($processRedirectToPaymentEvent->getProcessRedirect()) {
767
            $this->uriBuilder->reset()
768
                ->setTargetPageUid($paymentPid);
769
            $uri = $this->uriBuilder->uriFor(
770
                'redirect',
771
                [
772
                    'registration' => $registration,
773
                    'hmac' => $this->hashService->generateHmac('redirectAction-' . $registration->getUid()),
774
                ],
775
                'Payment',
776
                'sfeventmgt',
777
                'Pipayment'
778
            );
779
            return $this->redirectToUri($uri);
780
        }
781
782
        return null;
783
    }
784
785
    /**
786
     * Cancels the registration if possible and sends emails to admin and user
787
     */
788
    public function cancelRegistrationAction(int $reguid, string $hmac): ResponseInterface
789
    {
790
        $event = null;
791
792
        /* @var $registration Registration */
793
        [$failed, $registration, $messageKey, $titleKey] =
794
            $this->registrationService->checkCancelRegistration($reguid, $hmac);
795
796
        if ($failed === false) {
797
            $event = $registration->getEvent();
798
799
            // Send notifications (must run before cancelling the registration)
800
            $this->notificationService->sendUserMessage(
801
                $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

801
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
802
                $registration,
803
                $this->settings,
804
                MessageType::REGISTRATION_CANCELLED
805
            );
806
            $this->notificationService->sendAdminMessage(
807
                $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

807
                /** @scrutinizer ignore-type */ $registration->getEvent(),
Loading history...
808
                $registration,
809
                $this->settings,
810
                MessageType::REGISTRATION_CANCELLED
811
            );
812
813
            // First cancel depending registrations
814
            $processCancelDependingRegistrations = new ProcessCancelDependingRegistrationsEvent(
815
                $registration,
816
                $registration->getAmountOfRegistrations() > 1
817
            );
818
            $this->eventDispatcher->dispatch($processCancelDependingRegistrations);
819
            if ($processCancelDependingRegistrations->getProcessCancellation()) {
820
                $this->registrationService->cancelDependingRegistrations($registration);
821
            }
822
823
            // Finally cancel registration
824
            $this->registrationRepository->remove($registration);
825
826
            // Persist changes, so following functions can work with $event properties (e.g. amount of registrations)
827
            $this->persistAll();
828
829
            $afterRegistrationCancelledEvent = new AfterRegistrationCancelledEvent($registration, $this);
830
            $this->eventDispatcher->dispatch($afterRegistrationCancelledEvent);
831
832
            // Dispatch event, so waitlist registrations can be moved up and default move up process can be stopped
833
            $waitlistMoveUpEvent = new WaitlistMoveUpEvent($event, $this, 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

833
            $waitlistMoveUpEvent = new WaitlistMoveUpEvent(/** @scrutinizer ignore-type */ $event, $this, true);
Loading history...
834
            $this->eventDispatcher->dispatch($waitlistMoveUpEvent);
835
836
            // Move up waitlist registrations if configured on event basis and if not disabled by $waitlistMoveUpEvent
837
            if ($waitlistMoveUpEvent->getProcessDefaultMoveUp()) {
838
                $this->registrationService->moveUpWaitlistRegistrations($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

838
                $this->registrationService->moveUpWaitlistRegistrations(/** @scrutinizer ignore-type */ $event, $this->settings);
Loading history...
839
            }
840
841
            // Flush page cache for event, since amount of registrations has changed
842
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
843
        }
844
845
        $modifyCancelRegistrationViewVariablesEvent = new ModifyCancelRegistrationViewVariablesEvent(
846
            [
847
                'failed' => $failed,
848
                'messageKey' => $messageKey,
849
                'titleKey' => $titleKey,
850
                'event' => $event,
851
                'settings' => $this->settings,
852
            ],
853
            $this
854
        );
855
        $this->eventDispatcher->dispatch($modifyCancelRegistrationViewVariablesEvent);
856
        $variables = $modifyCancelRegistrationViewVariablesEvent->getVariables();
857
        $this->view->assignMultiple($variables);
858
859
        return $this->htmlResponse();
860
    }
861
862
    /**
863
     * Set date format for field startDate and endDate
864
     */
865
    public function initializeSearchAction(): void
866
    {
867
        if ($this->settings !== null && ($this->settings['search']['dateFormat'] ?? false)) {
868
            $this->arguments->getArgument('searchDemand')
869
                ->getPropertyMappingConfiguration()->forProperty('startDate')
870
                ->setTypeConverterOption(
871
                    DateTimeConverter::class,
872
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
873
                    $this->settings['search']['dateFormat']
874
                );
875
            $this->arguments->getArgument('searchDemand')
876
                ->getPropertyMappingConfiguration()->forProperty('endDate')
877
                ->setTypeConverterOption(
878
                    DateTimeConverter::class,
879
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
880
                    $this->settings['search']['dateFormat']
881
                );
882
        }
883
        if ($this->arguments->hasArgument('searchDemand')) {
884
            $propertyMappingConfiguration = $this->arguments->getArgument('searchDemand')
885
                ->getPropertyMappingConfiguration();
886
            $propertyMappingConfiguration->allowAllProperties();
887
            $propertyMappingConfiguration->setTypeConverterOption(
888
                PersistentObjectConverter::class,
889
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED,
890
                true
891
            );
892
        }
893
    }
894
895
    /**
896
     * Search view
897
     */
898
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = []): ResponseInterface
899
    {
900
        $eventDemand = EventDemand::createFromSettings($this->settings);
901
        $eventDemand->setSearchDemand($searchDemand);
902
        $foreignRecordDemand = ForeignRecordDemand::createFromSettings($this->settings);
903
        $categoryDemand = CategoryDemand::createFromSettings($this->settings);
904
905
        if ($searchDemand !== null) {
906
            $searchDemand->setFields($this->settings['search']['fields'] ?? '');
907
908
            $adjustTime = (bool)($this->settings['search']['adjustTime'] ?? false);
909
            if ($adjustTime && $searchDemand->getStartDate() !== null) {
910
                $searchDemand->getStartDate()->setTime(0, 0);
911
            }
912
913
            if ($adjustTime && $searchDemand->getEndDate() !== null) {
914
                $searchDemand->getEndDate()->setTime(23, 59, 59);
915
            }
916
        }
917
918
        if ($this->isOverwriteDemand($overwriteDemand)) {
919
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
920
        }
921
922
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
923
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
924
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
925
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
926
        $events = $this->eventRepository->findDemanded($eventDemand);
927
928
        $modifySearchViewVariablesEvent = new ModifySearchViewVariablesEvent(
929
            [
930
                'events' => $events,
931
                'categories' => $categories,
932
                'locations' => $locations,
933
                'organisators' => $organisators,
934
                'speakers' => $speakers,
935
                'searchDemand' => $searchDemand,
936
                'overwriteDemand' => $overwriteDemand,
937
                'settings' => $this->settings,
938
            ],
939
            $this
940
        );
941
        $this->eventDispatcher->dispatch($modifySearchViewVariablesEvent);
942
        $variables = $modifySearchViewVariablesEvent->getVariables();
943
        $this->view->assignMultiple($variables);
944
945
        return $this->htmlResponse();
946
    }
947
948
    /**
949
     * Returns if a demand object can be overwritten with the given overwriteDemand array
950
     */
951
    protected function isOverwriteDemand(array $overwriteDemand): bool
952
    {
953
        return (int)($this->settings['disableOverrideDemand'] ?? 0) !== 1 && $overwriteDemand !== [];
954
    }
955
956
    /**
957
     * If no event is given and the singleEvent setting is set, the configured single event is returned
958
     */
959
    protected function evaluateSingleEventSetting(?Event $event): ?Event
960
    {
961
        if ($event === null && (int)($this->settings['singleEvent'] ?? 0) > 0) {
962
            $event = $this->eventRepository->findByUid((int)$this->settings['singleEvent']);
963
        }
964
965
        return $event;
966
    }
967
968
    /**
969
     * If no event is given and the isShortcut setting is set, the event is displayed using the "Insert Record"
970
     * content element and should be loaded from contect object data
971
     */
972
    protected function evaluateIsShortcutSetting(?Event $event): ?Event
973
    {
974
        if ($event === null && (bool)($this->settings['detail']['isShortcut'] ?? false)) {
975
            $eventRawData = $this->request->getAttribute('currentContentObject')->data;
976
            $event = $this->eventRepository->findByUid($eventRawData['uid']);
977
        }
978
979
        return $event;
980
    }
981
982
    /**
983
     * Checks if the event pid could be found in the storagePage settings of the detail plugin and
984
     * if the pid could not be found it return null instead of the event object.
985
     */
986
    protected function checkPidOfEventRecord(Event $event): ?Event
987
    {
988
        $allowedStoragePages = GeneralUtility::trimExplode(
989
            ',',
990
            PageUtility::extendPidListByChildren(
991
                $this->settings['storagePage'] ?? '',
992
                (int)($this->settings['recursive'] ?? 0)
993
            ),
994
            true
995
        );
996
        if (count($allowedStoragePages) > 0 && !in_array($event->getPid(), $allowedStoragePages)) {
997
            $this->eventDispatcher->dispatch(new EventPidCheckFailedEvent($event, $this));
998
            $event = null;
999
        }
1000
1001
        return $event;
1002
    }
1003
1004
    /**
1005
     * Calls persistAll() of the persistenceManager
1006
     */
1007
    protected function persistAll(): void
1008
    {
1009
        GeneralUtility::makeInstance(PersistenceManager::class)->persistAll();
1010
    }
1011
1012
    /**
1013
     * Returns the language code of the current language
1014
     */
1015
    protected function getCurrentLanguageCode(): string
1016
    {
1017
        if ($this->request->getAttribute('language') instanceof SiteLanguage) {
1018
            /** @var SiteLanguage $siteLanguage */
1019
            $siteLanguage = $this->request->getAttribute('language');
1020
            return $siteLanguage->getLocale()->getLanguageCode();
1021
        }
1022
1023
        return '';
1024
    }
1025
}
1026