Passed
Push — develop ( c197be...8b8821 )
by Torben
02:11
created

EventController::evaluateEventPreviewSetting()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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

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

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

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

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