Completed
Push — registration_fields ( ba51da )
by Torben
10:23
created

setRegistrationFieldValuesToArguments()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 66
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 66
rs 7.0832
c 0
b 0
f 0
cc 7
eloc 39
nc 6
nop 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
namespace DERHANSEN\SfEventMgt\Controller;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand;
18
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
19
use DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand;
20
use DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand;
21
use DERHANSEN\SfEventMgt\Domain\Model\Event;
22
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
23
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
24
use DERHANSEN\SfEventMgt\Utility\MessageType;
25
use DERHANSEN\SfEventMgt\Utility\Page;
26
use TYPO3\CMS\Core\Utility\ArrayUtility;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Utility\HttpUtility;
29
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
30
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
31
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
32
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
33
use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
34
use TYPO3\CMS\Fluid\View\StandaloneView;
35
36
/**
37
 * EventController
38
 *
39
 * @author Torben Hansen <[email protected]>
40
 */
41
class EventController extends AbstractController
42
{
43
    /**
44
     * Properties in this array will be ignored by overwriteDemandObject()
45
     *
46
     * @var array
47
     */
48
    protected $ignoredSettingsForOverwriteDemand = ['storagepage', 'orderfieldallowed'];
49
50
    /**
51
     * Creates an event demand object with the given settings
52
     *
53
     * @param array $settings The settings
54
     *
55
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
56
     */
57
    public function createEventDemandObjectFromSettings(array $settings)
58
    {
59
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand */
60
        $demand = $this->objectManager->get(EventDemand::class);
61
        $demand->setDisplayMode($settings['displayMode']);
62
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
63
        $demand->setCategoryConjunction($settings['categoryConjunction']);
64
        $demand->setCategory($settings['category']);
65
        $demand->setIncludeSubcategories($settings['includeSubcategories']);
66
        $demand->setTopEventRestriction((int)$settings['topEventRestriction']);
67
        $demand->setOrderField($settings['orderField']);
68
        $demand->setOrderFieldAllowed($settings['orderFieldAllowed']);
69
        $demand->setOrderDirection($settings['orderDirection']);
70
        $demand->setQueryLimit($settings['queryLimit']);
71
        $demand->setLocation($settings['location']);
72
        $demand->setOrganisator($settings['organisator']);
73
        return $demand;
74
    }
75
76
    /**
77
     * Creates a foreign record demand object with the given settings
78
     *
79
     * @param array $settings The settings
80
     *
81
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand
82
     */
83
    public function createForeignRecordDemandObjectFromSettings(array $settings)
84
    {
85
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand $demand */
86
        $demand = $this->objectManager->get(ForeignRecordDemand::class);
87
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
88
        $demand->setRestrictForeignRecordsToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
89
        return $demand;
90
    }
91
92
    /**
93
     * Creates a category demand object with the given settings
94
     *
95
     * @param array $settings The settings
96
     *
97
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand
98
     */
99
    public function createCategoryDemandObjectFromSettings(array $settings)
100
    {
101
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand $demand */
102
        $demand = $this->objectManager->get(CategoryDemand::class);
103
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
104
        $demand->setRestrictToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
105
        $demand->setCategories($settings['categoryMenu']['categories']);
106
        $demand->setIncludeSubcategories($settings['categoryMenu']['includeSubcategories']);
107
        return $demand;
108
    }
109
110
    /**
111
     * Overwrites a given demand object by an propertyName =>  $propertyValue array
112
     *
113
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand Demand
114
     * @param array $overwriteDemand OwerwriteDemand
115
     *
116
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
117
     */
118
    protected function overwriteEventDemandObject(EventDemand $demand, array $overwriteDemand)
119
    {
120
        foreach ($this->ignoredSettingsForOverwriteDemand as $property) {
121
            unset($overwriteDemand[$property]);
122
        }
123
124
        foreach ($overwriteDemand as $propertyName => $propertyValue) {
125
            if (in_array(strtolower($propertyName), $this->ignoredSettingsForOverwriteDemand, true)) {
126
                continue;
127
            }
128
            \TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($demand, $propertyName, $propertyValue);
129
        }
130
        return $demand;
131
    }
132
133
    /**
134
     * Hook into request processing and catch exceptions
135
     *
136
     * @param RequestInterface $request
137
     * @param ResponseInterface $response
138
     * @throws \Exception
139
     */
140
    public function processRequest(RequestInterface $request, ResponseInterface $response)
141
    {
142
        try {
143
            parent::processRequest($request, $response);
144
        } catch (\Exception $exception) {
145
            $this->handleKnownExceptionsElseThrowAgain($exception);
146
        }
147
    }
148
149
    /**
150
     * Handle known exceptions
151
     *
152
     * @param \Exception $exception
153
     * @throws \Exception
154
     */
155
    private function handleKnownExceptionsElseThrowAgain(\Exception $exception)
156
    {
157
        $previousException = $exception->getPrevious();
158
        if (($this->actionMethodName === 'detailAction' || $this->actionMethodName === 'registrationAction')
159
            && $previousException instanceof \TYPO3\CMS\Extbase\Property\Exception
160
        ) {
161
            $this->handleEventNotFoundError($this->settings);
162
        } else {
163
            throw $exception;
164
        }
165
    }
166
167
    /**
168
     * Initialize list action and set format
169
     *
170
     * @return void
171
     */
172
    public function initializeListAction()
173
    {
174
        if (isset($this->settings['list']['format'])) {
175
            $this->request->setFormat($this->settings['list']['format']);
176
        }
177
    }
178
179
    /**
180
     * List view
181
     *
182
     * @param array $overwriteDemand OverwriteDemand
183
     *
184
     * @return void
185
     */
186
    public function listAction(array $overwriteDemand = [])
187
    {
188
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
189
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
190
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
191
        if ($this->isOverwriteDemand($overwriteDemand)) {
192
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
193
        }
194
        $events = $this->eventRepository->findDemanded($eventDemand);
195
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
196
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
197
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
198
        $this->view->assignMultiple([
199
            'events' => $events,
200
            'categories' => $categories,
201
            'locations' => $locations,
202
            'organisators' => $organisators,
203
            'overwriteDemand' => $overwriteDemand,
204
            'eventDemand' => $eventDemand
205
        ]);
206
    }
207
208
    /**
209
     * Calendar view
210
     *
211
     * @param array $overwriteDemand OverwriteDemand
212
     *
213
     * @return void
214
     */
215
    public function calendarAction(array $overwriteDemand = [])
216
    {
217
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
218
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
219
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
220
        if ($this->isOverwriteDemand($overwriteDemand)) {
221
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
222
        }
223
224
        // Set month/year to demand if not given
225
        if (!$eventDemand->getMonth()) {
226
            $currentMonth = date('n');
227
            $eventDemand->setMonth($currentMonth);
228
        } else {
229
            $currentMonth = $eventDemand->getMonth();
230
        }
231
        if (!$eventDemand->getYear()) {
232
            $currentYear = date('Y');
233
            $eventDemand->setYear($currentYear);
234
        } else {
235
            $currentYear = $eventDemand->getYear();
236
        }
237
238
        // Set demand from calendar date range instead of month / year
239
        if ((bool)$this->settings['calendar']['includeEventsForEveryDayOfAllCalendarWeeks']) {
240
            $eventDemand = $this->changeEventDemandToFullMonthDateRange($eventDemand);
241
        }
242
243
        $events = $this->eventRepository->findDemanded($eventDemand);
244
        $weeks = $this->calendarService->getCalendarArray(
245
            $currentMonth,
246
            $currentYear,
247
            strtotime('today midnight'),
248
            (int)$this->settings['calendar']['firstDayOfWeek'],
249
            $events
250
        );
251
252
        $values = [
253
            'weeks' => $weeks,
254
            'categories' => $this->categoryRepository->findDemanded($categoryDemand),
255
            'locations' => $this->locationRepository->findDemanded($foreignRecordDemand),
256
            'organisators' => $this->organisatorRepository->findDemanded($foreignRecordDemand),
257
            'eventDemand' => $eventDemand,
258
            'overwriteDemand' => $overwriteDemand,
259
            'currentPageId' => $GLOBALS['TSFE']->id,
260
            'firstDayOfMonth' => \DateTime::createFromFormat('d.m.Y', sprintf('1.%s.%s', $currentMonth, $currentMonth)),
261
            'previousMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '-1 month'),
262
            'nextMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '+1 month')
263
        ];
264
265
        $this->view->assignMultiple($values);
266
    }
267
268
    /**
269
     * Changes the given event demand object to select a date range for a calendar month including days of the previous
270
     * month for the first week and they days for the next month for the last week
271
     *
272
     * @param EventDemand $eventDemand
273
     * @return EventDemand
274
     */
275
    protected function changeEventDemandToFullMonthDateRange(EventDemand $eventDemand)
276
    {
277
        $calendarDateRange = $this->calendarService->getCalendarDateRange(
278
            $eventDemand->getMonth(),
279
            $eventDemand->getYear(),
280
            $this->settings['calendar']['firstDayOfWeek']
281
        );
282
283
        $eventDemand->setMonth(0);
284
        $eventDemand->setYear(0);
285
286
        $startDate = new \DateTime();
287
        $startDate->setTimestamp($calendarDateRange['firstDayOfCalendar']);
288
        $endDate = new \DateTime();
289
        $endDate->setTimestamp($calendarDateRange['lastDayOfCalendar']);
290
        $endDate->setTime(23, 59, 59);
291
292
        $searchDemand = new SearchDemand();
293
        $searchDemand->setStartDate($startDate);
294
        $searchDemand->setEndDate($endDate);
295
        $eventDemand->setSearchDemand($searchDemand);
296
        return $eventDemand;
297
    }
298
299
    /**
300
     * Detail view for an event
301
     *
302
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
303
     * @return string
304
     */
305
    public function detailAction(Event $event = null)
306
    {
307
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
308
            return $this->handleEventNotFoundError($this->settings);
309
        }
310
        $this->view->assign('event', $event);
311
    }
312
313
    /**
314
     * Error handling if event is not found
315
     *
316
     * @param array $settings
317
     * @return string
318
     */
319
    protected function handleEventNotFoundError($settings)
320
    {
321
        if (empty($settings['event']['errorHandling'])) {
322
            return null;
323
        }
324
325
        $configuration = GeneralUtility::trimExplode(',', $settings['event']['errorHandling'], true);
326
327
        switch ($configuration[0]) {
328
            case 'redirectToListView':
329
                $listPid = (int)$settings['listPid'] > 0 ? (int)$settings['listPid'] : 1;
330
                $this->redirect('list', null, null, null, $listPid);
331
                break;
332
            case 'pageNotFoundHandler':
333
                $GLOBALS['TSFE']->pageNotFoundAndExit('Event not found.');
334
                break;
335
            case 'showStandaloneTemplate':
336
                if (isset($configuration[2])) {
337
                    $statusCode = constant(HttpUtility::class . '::HTTP_STATUS_' . $configuration[2]);
338
                    HttpUtility::setResponseCode($statusCode);
339
                }
340
                $standaloneTemplate = $this->objectManager->get(StandaloneView::class);
341
                $standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($configuration[1]));
342
                return $standaloneTemplate->render();
343
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
344
            default:
345
        }
346
    }
347
348
    /**
349
     * Initiates the iCalendar download for the given event
350
     *
351
     * @param Event $event The event
352
     *
353
     * @return bool
354
     */
355
    public function icalDownloadAction(Event $event)
356
    {
357
        $this->icalendarService->downloadiCalendarFile($event);
358
        return false;
359
    }
360
361
    /**
362
     * Registration view for an event
363
     *
364
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
365
     *
366
     * @return string
367
     */
368
    public function registrationAction(Event $event = null)
369
    {
370
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
371
            return $this->handleEventNotFoundError($this->settings);
372
        }
373
        if ($event->getRestrictPaymentMethods()) {
0 ignored issues
show
Bug introduced by
It seems like $event is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
374
            $paymentMethods = $this->paymentService->getRestrictedPaymentMethods($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by parameter $event on line 368 can be null; however, DERHANSEN\SfEventMgt\Ser...trictedPaymentMethods() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
375
        } else {
376
            $paymentMethods = $this->paymentService->getPaymentMethods();
377
        }
378
379
        $this->view->assignMultiple([
380
            'event' => $event,
381
            'paymentMethods' => $paymentMethods,
382
        ]);
383
    }
384
385
    /**
386
     * Processes incoming registrations fields and adds field values to arguments
387
     *
388
     * @return void
389
     */
390
    protected function setRegistrationFieldValuesToArguments()
391
    {
392
        $arguments = $this->request->getArguments();
393
        if (!isset($arguments['registration']['fields']) || !isset($arguments['event'])) {
394
            return;
395
        }
396
397
        $registrationMvcArgument = $this->arguments->getArgument('registration');
398
        $propertyMapping = $registrationMvcArgument->getPropertyMappingConfiguration();
399
        $propertyMapping->allowProperties('fieldValues');
400
        $propertyMapping->allowCreationForSubProperty('fieldValues');
401
        $propertyMapping->allowModificationForSubProperty('fieldValues');
402
403
        // allow creation of new objects (for validation)
404
        $propertyMapping->setTypeConverterOptions(
405
            PersistentObjectConverter::class,
406
            [
407
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true,
408
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => true
409
            ]
410
        );
411
412
        // Set event to registration (required for validation)
413
        $event = $this->eventRepository->findByUid((int)$this->request->getArgument('event'));
414
        $propertyMapping->allowProperties('event');
415
        $propertyMapping->allowCreationForSubProperty('event');
416
        $propertyMapping->allowModificationForSubProperty('event');
417
        $arguments['registration']['event'] = (int)$this->request->getArgument('event');
418
419
        $index = 0;
420
        foreach ((array)$arguments['registration']['fields'] as $fieldUid => $value) {
421
            // Only accept registration fields of the current event
422
            if (!in_array((int)$fieldUid, $event->getRegistrationFieldsUids(), true)) {
423
                continue;
424
            }
425
426
            // allow subvalues in new property mapper
427
            $propertyMapping->forProperty('fieldValues')->allowProperties($index);
428
            $propertyMapping->forProperty('fieldValues.' . $index)->allowAllProperties();
429
            $propertyMapping->allowCreationForSubProperty('fieldValues.' . $index);
430
            $propertyMapping->allowModificationForSubProperty('fieldValues.' . $index);
431
432
            if (is_array($value)) {
433
                if (empty($value)) {
434
                    $value = '';
435
                } else {
436
                    $value = json_encode($value);
437
                }
438
            }
439
440
            /** @var Registration\Field $field */
441
            $field = $this->fieldRepository->findByUid((int)$fieldUid);
442
443
            $arguments['registration']['fieldValues'][$index] = [
444
                'value' => $value,
445
                'field' => strval($fieldUid),
446
                'valueType' => $field->getValueType()
447
            ];
448
449
            $index++;
450
        }
451
452
        // Remove temporary "fields" field
453
        $arguments = ArrayUtility::removeByPath($arguments, 'registration/fields');
454
        $this->request->setArguments($arguments);
455
    }
456
457
    /**
458
     * Set date format for field dateOfBirth
459
     *
460
     * @return void
461
     */
462
    public function initializeSaveRegistrationAction()
463
    {
464
        $this->arguments->getArgument('registration')
465
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
466
            ->setTypeConverterOption(
467
                DateTimeConverter::class,
468
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
469
                $this->settings['registration']['formatDateOfBirth']
470
            );
471
        $this->setRegistrationFieldValuesToArguments();
472
    }
473
474
    /**
475
     * Saves the registration
476
     *
477
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
478
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
479
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationFieldValidator
480
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator
481
     *
482
     * @return void
483
     */
484
    public function saveRegistrationAction(Registration $registration, Event $event)
485
    {
486
        $autoConfirmation = (bool)$this->settings['registration']['autoConfirmation'] || $event->getEnableAutoconfirm();
487
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
488
        $success = $this->registrationService->checkRegistrationSuccess($event, $registration, $result);
489
490
        // Save registration if no errors
491
        if ($success) {
492
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
493
                $event,
494
                $registration->getAmountOfRegistrations()
495
            );
496
            $linkValidity = (int)$this->settings['confirmation']['linkValidity'];
497
            if ($linkValidity === 0) {
498
                // Use 3600 seconds as default value if not set
499
                $linkValidity = 3600;
500
            }
501
            $confirmationUntil = new \DateTime();
502
            $confirmationUntil->add(new \DateInterval('PT' . $linkValidity . 'S'));
503
504
            $registration->setEvent($event);
505
            $registration->setPid($event->getPid());
506
            $registration->setConfirmationUntil($confirmationUntil);
507
            $registration->setLanguage($GLOBALS['TSFE']->config['config']['language']);
508
            $registration->setFeUser($this->registrationService->getCurrentFeUserObject());
0 ignored issues
show
Documentation introduced by
$this->registrationServi...etCurrentFeUserObject() is of type object|null, but the function expects a object<TYPO3\CMS\Extbase...ain\Model\FrontendUser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
509
            $registration->setWaitlist($isWaitlistRegistration);
510
            $registration->_setProperty('_languageUid', $GLOBALS['TSFE']->sys_language_uid);
511
            $this->registrationRepository->add($registration);
512
513
            // Persist registration, so we have an UID
514
            $this->objectManager->get(PersistenceManager::class)->persistAll();
515
516
            // Add new registration (or waitlist registration) to event
517
            if ($isWaitlistRegistration) {
518
                $event->addRegistrationWaitlist($registration);
519
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
520
            } else {
521
                $event->addRegistration($registration);
522
                $messageType = MessageType::REGISTRATION_NEW;
523
            }
524
            $this->eventRepository->update($event);
525
526
            // Send notifications to user and admin if confirmation link should be sent
527
            if (!$autoConfirmation) {
528
                $this->notificationService->sendUserMessage(
529
                    $event,
530
                    $registration,
531
                    $this->settings,
532
                    $messageType
533
                );
534
                $this->notificationService->sendAdminMessage(
535
                    $event,
536
                    $registration,
537
                    $this->settings,
538
                    $messageType
539
                );
540
            }
541
542
            // Create given amount of registrations if necessary
543
            if ($registration->getAmountOfRegistrations() > 1) {
544
                $this->registrationService->createDependingRegistrations($registration);
545
            }
546
547
            // Clear cache for configured pages
548
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
549
        }
550
551
        if ($autoConfirmation && $success) {
552
            $this->redirect(
553
                'confirmRegistration',
554
                null,
555
                null,
556
                [
557
                    'reguid' => $registration->getUid(),
558
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid())
559
                ]
560
            );
561
        } else {
562
            $this->redirect(
563
                'saveRegistrationResult',
564
                null,
565
                null,
566
                [
567
                    'result' => $result,
568
                    'eventuid' => $event->getUid(),
569
                    'hmac' => $this->hashService->generateHmac('event-' . $event->getUid())
570
                ]
571
            );
572
        }
573
    }
574
575
    /**
576
     * Shows the result of the saveRegistrationAction
577
     *
578
     * @param int $result Result
579
     * @param int $eventuid
580
     * @param string $hmac
581
     *
582
     * @return void
583
     */
584
    public function saveRegistrationResultAction($result, $eventuid, $hmac)
585
    {
586
        $event = null;
587
588
        switch ($result) {
589
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
590
                $messageKey = 'event.message.registrationsuccessful';
591
                $titleKey = 'registrationResult.title.successful';
592
                break;
593
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
594
                $messageKey = 'event.message.registrationwaitlistsuccessful';
595
                $titleKey = 'registrationWaitlistResult.title.successful';
596
                break;
597
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
598
                $messageKey = 'event.message.registrationfailedeventexpired';
599
                $titleKey = 'registrationResult.title.failed';
600
                break;
601
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
602
                $messageKey = 'event.message.registrationfailedmaxparticipants';
603
                $titleKey = 'registrationResult.title.failed';
604
                break;
605
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
606
                $messageKey = 'event.message.registrationfailednotenabled';
607
                $titleKey = 'registrationResult.title.failed';
608
                break;
609
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
610
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
611
                $titleKey = 'registrationResult.title.failed';
612
                break;
613
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
614
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
615
                $titleKey = 'registrationResult.title.failed';
616
                break;
617
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
618
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
619
                $titleKey = 'registrationResult.title.failed';
620
                break;
621
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
622
                $messageKey = 'event.message.registrationfailedemailnotunique';
623
                $titleKey = 'registrationResult.title.failed';
624
                break;
625
            default:
626
                $messageKey = '';
627
                $titleKey = '';
628
        }
629
630
        if (!$this->hashService->validateHmac('event-' . $eventuid, $hmac)) {
631
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
632
            $titleKey = 'registrationResult.title.failed';
633
        } else {
634
            $event = $this->eventRepository->findByUid((int)$eventuid);
635
        }
636
637
        $this->view->assignMultiple([
638
            'messageKey' => $messageKey,
639
            'titleKey' => $titleKey,
640
            'event' => $event,
641
        ]);
642
    }
643
644
    /**
645
     * Confirms the registration if possible and sends e-mails to admin and user
646
     *
647
     * @param int $reguid UID of registration
648
     * @param string $hmac HMAC for parameters
649
     *
650
     * @return void
651
     */
652
    public function confirmRegistrationAction($reguid, $hmac)
653
    {
654
        $event = null;
655
656
        /* @var $registration Registration */
657
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkConfirmRegistration(
658
            $reguid,
659
            $hmac
660
        );
661
662
        if ($failed === false) {
663
            $registration->setConfirmed(true);
664
            $event = $registration->getEvent();
665
            $this->registrationRepository->update($registration);
666
667
            $messageType = MessageType::REGISTRATION_CONFIRMED;
668
            if ($registration->getWaitlist()) {
669
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
670
            }
671
672
            // Send notifications to user and admin
673
            $this->notificationService->sendUserMessage(
674
                $registration->getEvent(),
675
                $registration,
676
                $this->settings,
677
                $messageType
678
            );
679
            $this->notificationService->sendAdminMessage(
680
                $registration->getEvent(),
681
                $registration,
682
                $this->settings,
683
                $messageType
684
            );
685
686
            // Confirm registrations depending on main registration if necessary
687
            if ($registration->getAmountOfRegistrations() > 1) {
688
                $this->registrationService->confirmDependingRegistrations($registration);
689
            }
690
        }
691
692
        // Redirect to payment provider if payment/redirect is enabled
693
        $paymentPid = (int)$this->settings['paymentPid'];
694
        if (!$failed && $paymentPid > 0 && $this->registrationService->redirectPaymentEnabled($registration)) {
695
            $this->uriBuilder->reset()
696
                ->setTargetPageUid($paymentPid)
697
                ->setUseCacheHash(false);
698
            $uri =  $this->uriBuilder->uriFor(
699
                'redirect',
700
                [
701
                    'registration' => $registration,
702
                    'hmac' => $this->hashService->generateHmac('redirectAction-' . $registration->getUid())
703
                ],
704
                'Payment',
705
                'sfeventmgt',
706
                'Pipayment'
707
            );
708
            $this->redirectToUri($uri);
709
        }
710
711
        $this->view->assignMultiple([
712
            'messageKey' => $messageKey,
713
            'titleKey' => $titleKey,
714
            'event' => $event,
715
        ]);
716
    }
717
718
    /**
719
     * Cancels the registration if possible and sends e-mails to admin and user
720
     *
721
     * @param int $reguid UID of registration
722
     * @param string $hmac HMAC for parameters
723
     *
724
     * @return void
725
     */
726
    public function cancelRegistrationAction($reguid, $hmac)
727
    {
728
        $event = null;
729
730
        /* @var $registration Registration */
731
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkCancelRegistration($reguid, $hmac);
732
733
        if ($failed === false) {
734
            $event = $registration->getEvent();
735
736
            // Send notifications (must run before cancelling the registration)
737
            $this->notificationService->sendUserMessage(
738
                $registration->getEvent(),
739
                $registration,
740
                $this->settings,
741
                MessageType::REGISTRATION_CANCELLED
742
            );
743
            $this->notificationService->sendAdminMessage(
744
                $registration->getEvent(),
745
                $registration,
746
                $this->settings,
747
                MessageType::REGISTRATION_CANCELLED
748
            );
749
750
            // First cancel depending registrations
751
            if ($registration->getAmountOfRegistrations() > 1) {
752
                $this->registrationService->cancelDependingRegistrations($registration);
753
            }
754
755
            // Finally cancel registration
756
            $this->registrationRepository->remove($registration);
757
758
            // Clear cache for configured pages
759
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
760
        }
761
762
        $this->view->assignMultiple([
763
            'messageKey' => $messageKey,
764
            'titleKey' => $titleKey,
765
            'event' => $event,
766
        ]);
767
    }
768
769
    /**
770
     * Set date format for field startDate and endDate
771
     *
772
     * @return void
773
     */
774
    public function initializeSearchAction()
775
    {
776
        if ($this->settings !== null && $this->settings['search']['dateFormat']) {
777
            $this->arguments->getArgument('searchDemand')
778
                ->getPropertyMappingConfiguration()->forProperty('startDate')
779
                ->setTypeConverterOption(
780
                    DateTimeConverter::class,
781
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
782
                    $this->settings['search']['dateFormat']
783
                );
784
            $this->arguments->getArgument('searchDemand')
785
                ->getPropertyMappingConfiguration()->forProperty('endDate')
786
                ->setTypeConverterOption(
787
                    DateTimeConverter::class,
788
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
789
                    $this->settings['search']['dateFormat']
790
                );
791
        }
792
    }
793
794
    /**
795
     * Search view
796
     *
797
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
798
     * @param array $overwriteDemand OverwriteDemand
799
     *
800
     * @return void
801
     */
802
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
803
    {
804
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
805
        $eventDemand->setSearchDemand($searchDemand);
0 ignored issues
show
Bug introduced by
It seems like $searchDemand defined by parameter $searchDemand on line 802 can be null; however, DERHANSEN\SfEventMgt\Dom...mand::setSearchDemand() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
806
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
807
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
808
809
        if ($searchDemand !== null) {
810
            $searchDemand->setFields($this->settings['search']['fields']);
811
812
            if ($this->settings['search']['adjustTime'] && $searchDemand->getStartDate() !== null) {
813
                $searchDemand->getStartDate()->setTime(0, 0, 0);
814
            }
815
816
            if ($this->settings['search']['adjustTime'] && $searchDemand->getEndDate() !== null) {
817
                $searchDemand->getEndDate()->setTime(23, 59, 59);
818
            }
819
        }
820
821
        if ($this->isOverwriteDemand($overwriteDemand)) {
822
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
823
        }
824
825
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
826
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
827
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
828
829
        $events = $this->eventRepository->findDemanded($eventDemand);
830
831
        $this->view->assignMultiple([
832
            'events' => $events,
833
            'categories' => $categories,
834
            'locations' => $locations,
835
            'organisators' => $organisators,
836
            'searchDemand' => $searchDemand,
837
            'overwriteDemand' => $overwriteDemand,
838
        ]);
839
    }
840
841
    /**
842
     * Returns if a demand object can be overwritten with the given overwriteDemand array
843
     *
844
     * @param array $overwriteDemand
845
     * @return bool
846
     */
847
    protected function isOverwriteDemand($overwriteDemand)
848
    {
849
        return $this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== [];
850
    }
851
}
852