Completed
Push — development ( d54d2c...807851 )
by Torben
03:44
created

EventController::saveRegistrationAction()   C

Complexity

Conditions 9
Paths 68

Size

Total Lines 90
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 9.9613

Importance

Changes 0
Metric Value
dl 0
loc 90
ccs 44
cts 57
cp 0.7719
rs 5.1827
c 0
b 0
f 0
cc 9
eloc 58
nc 68
nop 2
crap 9.9613

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 Extension "sf_event_mgt" for TYPO3 CMS.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.txt file that was distributed with this source code.
9
 */
10
11
use DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand;
12
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
13
use DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand;
14
use DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand;
15
use DERHANSEN\SfEventMgt\Domain\Model\Event;
16
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
17
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
18
use DERHANSEN\SfEventMgt\Utility\MessageType;
19
use DERHANSEN\SfEventMgt\Utility\Page;
20
use TYPO3\CMS\Core\Utility\ArrayUtility;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Core\Utility\HttpUtility;
23
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
24
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
25
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
26
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
27
use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
28
use TYPO3\CMS\Fluid\View\StandaloneView;
29
30
/**
31
 * EventController
32
 *
33
 * @author Torben Hansen <[email protected]>
34
 */
35
class EventController extends AbstractController
36
{
37
    /**
38
     * Assign contentObjectData and pageData to earch view
39
     *
40
     * @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view
41
     */
42
    protected function initializeView(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view)
43
    {
44
        $view->assign('contentObjectData', $this->configurationManager->getContentObject()->data);
45
        if (is_object($GLOBALS['TSFE'])) {
46
            $view->assign('pageData', $GLOBALS['TSFE']->page);
47
        }
48
        parent::initializeView($view);
49
    }
50
51
    /**
52
     * Properties in this array will be ignored by overwriteDemandObject()
53
     *
54
     * @var array
55
     */
56
    protected $ignoredSettingsForOverwriteDemand = ['storagepage', 'orderfieldallowed'];
57
58
    /**
59
     * Creates an event demand object with the given settings
60
     *
61
     * @param array $settings The settings
62
     *
63
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
64
     */
65
    public function createEventDemandObjectFromSettings(array $settings)
66
    {
67
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand */
68
        $demand = $this->objectManager->get(EventDemand::class);
69
        $demand->setDisplayMode($settings['displayMode']);
70
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
71
        $demand->setCategoryConjunction($settings['categoryConjunction']);
72
        $demand->setCategory($settings['category']);
73
        $demand->setIncludeSubcategories($settings['includeSubcategories']);
74
        $demand->setTopEventRestriction((int)$settings['topEventRestriction']);
75
        $demand->setOrderField($settings['orderField']);
76
        $demand->setOrderFieldAllowed($settings['orderFieldAllowed']);
77
        $demand->setOrderDirection($settings['orderDirection']);
78
        $demand->setQueryLimit($settings['queryLimit']);
79
        $demand->setLocation($settings['location']);
80
        $demand->setOrganisator($settings['organisator']);
81
        return $demand;
82
    }
83
84
    /**
85
     * Creates a foreign record demand object with the given settings
86
     *
87
     * @param array $settings The settings
88
     *
89
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand
90
     */
91
    public function createForeignRecordDemandObjectFromSettings(array $settings)
92
    {
93
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand $demand */
94
        $demand = $this->objectManager->get(ForeignRecordDemand::class);
95
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
96
        $demand->setRestrictForeignRecordsToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
97
        return $demand;
98
    }
99
100
    /**
101
     * Creates a category demand object with the given settings
102
     *
103
     * @param array $settings The settings
104
     *
105
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand
106
     */
107
    public function createCategoryDemandObjectFromSettings(array $settings)
108
    {
109
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand $demand */
110
        $demand = $this->objectManager->get(CategoryDemand::class);
111
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
112
        $demand->setRestrictToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
113
        $demand->setCategories($settings['categoryMenu']['categories']);
114
        $demand->setIncludeSubcategories($settings['categoryMenu']['includeSubcategories']);
115
        return $demand;
116
    }
117
118
    /**
119
     * Overwrites a given demand object by an propertyName =>  $propertyValue array
120
     *
121
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand Demand
122
     * @param array $overwriteDemand OwerwriteDemand
123
     *
124
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
125
     */
126
    protected function overwriteEventDemandObject(EventDemand $demand, array $overwriteDemand)
127
    {
128
        foreach ($this->ignoredSettingsForOverwriteDemand as $property) {
129
            unset($overwriteDemand[$property]);
130
        }
131
132
        foreach ($overwriteDemand as $propertyName => $propertyValue) {
133
            if (in_array(strtolower($propertyName), $this->ignoredSettingsForOverwriteDemand, true)) {
134
                continue;
135
            }
136
            \TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($demand, $propertyName, $propertyValue);
137 1
        }
138
        return $demand;
139
    }
140 1
141 1
    /**
142 1
     * Hook into request processing and catch exceptions
143 1
     *
144 1
     * @param RequestInterface $request
145 1
     * @param ResponseInterface $response
146 1
     * @throws \Exception
147 1
     */
148 1
    public function processRequest(RequestInterface $request, ResponseInterface $response)
149 1
    {
150 1
        try {
151
            parent::processRequest($request, $response);
152
        } catch (\Exception $exception) {
153
            $this->handleKnownExceptionsElseThrowAgain($exception);
154
        }
155
    }
156
157
    /**
158
     * Handle known exceptions
159
     *
160
     * @param \Exception $exception
161
     * @throws \Exception
162
     */
163
    private function handleKnownExceptionsElseThrowAgain(\Exception $exception)
164
    {
165
        $previousException = $exception->getPrevious();
166
        if (($this->actionMethodName === 'detailAction' || $this->actionMethodName === 'registrationAction')
167
            && $previousException instanceof \TYPO3\CMS\Extbase\Property\Exception
168
        ) {
169
            $this->handleEventNotFoundError($this->settings);
170
        } else {
171
            throw $exception;
172
        }
173
    }
174
175
    /**
176 1
     * Initialize list action and set format
177
     *
178
     * @return void
179 1
     */
180 1
    public function initializeListAction()
181 1
    {
182 1
        if (isset($this->settings['list']['format'])) {
183 1
            $this->request->setFormat($this->settings['list']['format']);
184 1
        }
185
    }
186
187
    /**
188
     * List view
189
     *
190
     * @param array $overwriteDemand OverwriteDemand
191
     *
192
     * @return void
193
     */
194
    public function listAction(array $overwriteDemand = [])
195 2
    {
196
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
197 2
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
198 2
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
199 2
        if ($this->isOverwriteDemand($overwriteDemand)) {
200
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
201 2
        }
202 2
        $events = $this->eventRepository->findDemanded($eventDemand);
203 2
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
204 2
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
205
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
206
        $this->view->assignMultiple([
207
            'events' => $events,
208
            'categories' => $categories,
209
            'locations' => $locations,
210
            'organisators' => $organisators,
211
            'overwriteDemand' => $overwriteDemand,
212
            'eventDemand' => $eventDemand
213
        ]);
214
    }
215
216
    /**
217
     * Calendar view
218
     *
219
     * @param array $overwriteDemand OverwriteDemand
220
     *
221
     * @return void
222
     */
223
    public function calendarAction(array $overwriteDemand = [])
224
    {
225
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
226 3
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
227
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
228 3
        if ($this->isOverwriteDemand($overwriteDemand)) {
229 3
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
230 3
        }
231 3
232 1
        // Set month/year to demand if not given
233 1
        if (!$eventDemand->getMonth()) {
234 3
            $currentMonth = date('n');
235 3
            $eventDemand->setMonth($currentMonth);
236 3
        } else {
237 3
            $currentMonth = $eventDemand->getMonth();
238 3
        }
239 3
        if (!$eventDemand->getYear()) {
240 3
            $currentYear = date('Y');
241 3
            $eventDemand->setYear($currentYear);
242
        } else {
243
            $currentYear = $eventDemand->getYear();
244
        }
245
246
        // Set demand from calendar date range instead of month / year
247
        if ((bool)$this->settings['calendar']['includeEventsForEveryDayOfAllCalendarWeeks']) {
248
            $eventDemand = $this->changeEventDemandToFullMonthDateRange($eventDemand);
249
        }
250 1
251
        $events = $this->eventRepository->findDemanded($eventDemand);
252 1
        $weeks = $this->calendarService->getCalendarArray(
253 1
            $currentMonth,
254
            $currentYear,
255
            strtotime('today midnight'),
256
            (int)$this->settings['calendar']['firstDayOfWeek'],
257
            $events
258
        );
259
260
        $values = [
261
            'weeks' => $weeks,
262 1
            'categories' => $this->categoryRepository->findDemanded($categoryDemand),
263
            'locations' => $this->locationRepository->findDemanded($foreignRecordDemand),
264 1
            'organisators' => $this->organisatorRepository->findDemanded($foreignRecordDemand),
265 1
            'eventDemand' => $eventDemand,
266
            'overwriteDemand' => $overwriteDemand,
267
            'currentPageId' => $GLOBALS['TSFE']->id,
268
            'firstDayOfMonth' => \DateTime::createFromFormat('d.m.Y', sprintf('1.%s.%s', $currentMonth, $currentYear)),
269
            'previousMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '-1 month'),
270
            'nextMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '+1 month')
271
        ];
272
273
        $this->view->assignMultiple($values);
274
    }
275 1
276
    /**
277 1
     * Changes the given event demand object to select a date range for a calendar month including days of the previous
278
     * month for the first week and they days for the next month for the last week
279
     *
280 1
     * @param EventDemand $eventDemand
281
     * @return EventDemand
282 1
     */
283 1
    protected function changeEventDemandToFullMonthDateRange(EventDemand $eventDemand)
284 1
    {
285
        $calendarDateRange = $this->calendarService->getCalendarDateRange(
286
            $eventDemand->getMonth(),
287
            $eventDemand->getYear(),
288
            $this->settings['calendar']['firstDayOfWeek']
289
        );
290
291 1
        $eventDemand->setMonth(0);
292
        $eventDemand->setYear(0);
293 1
294 1
        $startDate = new \DateTime();
295 1
        $startDate->setTimestamp($calendarDateRange['firstDayOfCalendar']);
296 1
        $endDate = new \DateTime();
297 1
        $endDate->setTimestamp($calendarDateRange['lastDayOfCalendar']);
298 1
        $endDate->setTime(23, 59, 59);
299 1
300 1
        $searchDemand = new SearchDemand();
301
        $searchDemand->setStartDate($startDate);
302
        $searchDemand->setEndDate($endDate);
303
        $eventDemand->setSearchDemand($searchDemand);
304
        return $eventDemand;
305
    }
306
307
    /**
308
     * Detail view for an event
309
     *
310
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
311 11
     * @return string
312
     */
313 11
    public function detailAction(Event $event = null)
314 11
    {
315 11
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
316
            return $this->handleEventNotFoundError($this->settings);
317
        }
318 11
        $this->view->assign('event', $event);
319 4
    }
320 4
321 4
    /**
322 4
     * Error handling if event is not found
323 4
     *
324 4
     * @param array $settings
325
     * @return string
326 4
     */
327 4
    protected function handleEventNotFoundError($settings)
328 4
    {
329 4
        if (empty($settings['event']['errorHandling'])) {
330
            return null;
331 4
        }
332 4
333 4
        $configuration = GeneralUtility::trimExplode(',', $settings['event']['errorHandling'], true);
334 4
335 4
        switch ($configuration[0]) {
336 4
            case 'redirectToListView':
337 4
                $listPid = (int)$settings['listPid'] > 0 ? (int)$settings['listPid'] : 1;
338 4
                $this->redirect('list', null, null, null, $listPid);
339
                break;
340
            case 'pageNotFoundHandler':
341 4
                $GLOBALS['TSFE']->pageNotFoundAndExit('Event not found.');
342
                break;
343
            case 'showStandaloneTemplate':
344 4
                if (isset($configuration[2])) {
345 1
                    $statusCode = constant(HttpUtility::class . '::HTTP_STATUS_' . $configuration[2]);
346 1
                    HttpUtility::setResponseCode($statusCode);
347 1
                }
348 3
                $standaloneTemplate = $this->objectManager->get(StandaloneView::class);
349 3
                $standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($configuration[1]));
350
                return $standaloneTemplate->render();
351 4
                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...
352
            default:
353
        }
354 4
    }
355 3
356 3
    /**
357 3
     * Initiates the iCalendar download for the given event
358 3
     *
359
     * @param Event $event The event
360 3
     *
361 3
     * @return bool
362 3
     */
363 3
    public function icalDownloadAction(Event $event)
364 3
    {
365
        $this->icalendarService->downloadiCalendarFile($event);
366 3
        return false;
367 3
    }
368
369
    /**
370 4
     * Registration view for an event
371 1
     *
372 1
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
373
     *
374
     * @return string
375 4
     */
376 4
    public function registrationAction(Event $event = null)
377
    {
378 11
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
379 1
            return $this->handleEventNotFoundError($this->settings);
380 1
        }
381 1
        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...
382 1
            $paymentMethods = $this->paymentService->getRestrictedPaymentMethods($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by parameter $event on line 376 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...
383
        } else {
384 1
            $paymentMethods = $this->paymentService->getPaymentMethods();
385 1
        }
386 1
387 1
        $this->view->assignMultiple([
388 1
            'event' => $event,
389 10
            'paymentMethods' => $paymentMethods,
390 10
        ]);
391 10
    }
392 10
393 10
    /**
394 10
     * Processes incoming registrations fields and adds field values to arguments
395
     *
396 11
     * @return void
397
     */
398
    protected function setRegistrationFieldValuesToArguments()
399
    {
400
        $arguments = $this->request->getArguments();
401
        if (!isset($arguments['registration']['fields']) || !isset($arguments['event'])) {
402
            return;
403
        }
404
405 9
        $registrationMvcArgument = $this->arguments->getArgument('registration');
406
        $propertyMapping = $registrationMvcArgument->getPropertyMappingConfiguration();
407
        $propertyMapping->allowProperties('fieldValues');
408 9
        $propertyMapping->allowCreationForSubProperty('fieldValues');
409 1
        $propertyMapping->allowModificationForSubProperty('fieldValues');
410 1
411 1
        // allow creation of new objects (for validation)
412 8
        $propertyMapping->setTypeConverterOptions(
413
            PersistentObjectConverter::class,
414
            [
415
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true,
416 8
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => true
417 1
            ]
418 1
        );
419 1
420 7
        // Set event to registration (required for validation)
421 1
        $event = $this->eventRepository->findByUid((int)$this->request->getArgument('event'));
422 1
        $propertyMapping->allowProperties('event');
423 1
        $propertyMapping->allowCreationForSubProperty('event');
424 6
        $propertyMapping->allowModificationForSubProperty('event');
425 1
        $arguments['registration']['event'] = (int)$this->request->getArgument('event');
426 1
427 1
        $index = 0;
428 5
        foreach ((array)$arguments['registration']['fields'] as $fieldUid => $value) {
429 1
            // Only accept registration fields of the current event
430 1
            if (!in_array((int)$fieldUid, $event->getRegistrationFieldsUids(), true)) {
431 1
                continue;
432 4
            }
433 1
434 1
            // allow subvalues in new property mapper
435 1
            $propertyMapping->forProperty('fieldValues')->allowProperties($index);
436 3
            $propertyMapping->forProperty('fieldValues.' . $index)->allowAllProperties();
437 1
            $propertyMapping->allowCreationForSubProperty('fieldValues.' . $index);
438 1
            $propertyMapping->allowModificationForSubProperty('fieldValues.' . $index);
439 1
440 2
            if (is_array($value)) {
441 1
                if (empty($value)) {
442 1
                    $value = '';
443 1
                } else {
444 1
                    $value = json_encode($value);
445 1
                }
446 1
            }
447 1
448
            /** @var Registration\Field $field */
449 9
            $field = $this->fieldRepository->findByUid((int)$fieldUid);
450 9
451 9
            $arguments['registration']['fieldValues'][$index] = [
452
                'value' => $value,
453
                'field' => strval($fieldUid),
454
                'valueType' => $field->getValueType()
455
            ];
456
457
            $index++;
458
        }
459
460
        // Remove temporary "fields" field
461 3
        $arguments = ArrayUtility::removeByPath($arguments, 'registration/fields');
462
        $this->request->setArguments($arguments);
463
    }
464 3
465
    /**
466 3
     * Set date format for field dateOfBirth
467 2
     *
468 2
     * @return void
469
     */
470 2
    public function initializeSaveRegistrationAction()
471 2
    {
472 1
        $this->arguments->getArgument('registration')
473 1
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
474
            ->setTypeConverterOption(
475
                DateTimeConverter::class,
476 2
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
477 2
                $this->settings['registration']['formatDateOfBirth']
478 2
            );
479 2
        $this->setRegistrationFieldValuesToArguments();
480
    }
481 2
482 2
    /**
483 2
     * Saves the registration
484 2
     *
485 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
486
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
487 2
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationFieldValidator
488
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator
489
     *
490 2
     * @return void
491 2
     */
492 2
    public function saveRegistrationAction(Registration $registration, Event $event)
493 2
    {
494
        $autoConfirmation = (bool)$this->settings['registration']['autoConfirmation'] || $event->getEnableAutoconfirm();
495
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
496 3
        $success = $this->registrationService->checkRegistrationSuccess($event, $registration, $result);
497 3
498
        // Save registration if no errors
499
        if ($success) {
500
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
501
                $event,
502
                $registration->getAmountOfRegistrations()
503
            );
504
            $linkValidity = (int)$this->settings['confirmation']['linkValidity'];
505
            if ($linkValidity === 0) {
506
                // Use 3600 seconds as default value if not set
507
                $linkValidity = 3600;
508
            }
509
            $confirmationUntil = new \DateTime();
510
            $confirmationUntil->add(new \DateInterval('PT' . $linkValidity . 'S'));
511
512
            $registration->setEvent($event);
513
            $registration->setPid($event->getPid());
514 3
            $registration->setConfirmationUntil($confirmationUntil);
515 3
            $registration->setLanguage($GLOBALS['TSFE']->config['config']['language']);
516 3
            $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...
517
            $registration->setWaitlist($isWaitlistRegistration);
518
            $registration->_setProperty('_languageUid', $GLOBALS['TSFE']->sys_language_uid);
519
            $this->registrationRepository->add($registration);
520
521
            // Persist registration, so we have an UID
522
            $this->objectManager->get(PersistenceManager::class)->persistAll();
523
524
            // Add new registration (or waitlist registration) to event
525
            if ($isWaitlistRegistration) {
526 2
                $event->addRegistrationWaitlist($registration);
527
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
528
            } else {
529 2
                $event->addRegistration($registration);
530
                $messageType = MessageType::REGISTRATION_NEW;
531 2
            }
532
            $this->eventRepository->update($event);
533 1
534 1
            // Send notifications to user and admin if confirmation link should be sent
535 1
            if (!$autoConfirmation) {
536 1
                $this->notificationService->sendUserMessage(
537
                    $event,
538 1
                    $registration,
539 1
                    $this->settings,
540 1
                    $messageType
541 1
                );
542 1
                $this->notificationService->sendAdminMessage(
543
                    $event,
544 1
                    $registration,
545
                    $this->settings,
546
                    $messageType
547 1
                );
548 1
            }
549 1
550
            // Create given amount of registrations if necessary
551
            if ($registration->getAmountOfRegistrations() > 1) {
552 1
                $this->registrationService->createDependingRegistrations($registration);
553
            }
554
555 1
            // Clear cache for configured pages
556 1
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
557 2
        }
558 2
559 2
        if ($autoConfirmation && $success) {
560
            $this->redirect(
561
                'confirmRegistration',
562
                null,
563
                null,
564
                [
565
                    'reguid' => $registration->getUid(),
566 1
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid())
567
                ]
568 1
            );
569 1
        } else {
570 1
            $this->redirect(
571 1
                'saveRegistrationResult',
572 1
                null,
573 1
                null,
574 1
                [
575 1
                    'result' => $result,
576 1
                    'eventuid' => $event->getUid(),
577 1
                    'hmac' => $this->hashService->generateHmac('event-' . $event->getUid())
578 1
                ]
579 1
            );
580 1
        }
581 1
    }
582 1
583 1
    /**
584 1
     * Shows the result of the saveRegistrationAction
585
     *
586
     * @param int $result Result
587
     * @param int $eventuid
588
     * @param string $hmac
589
     *
590
     * @return void
591
     */
592
    public function saveRegistrationResultAction($result, $eventuid, $hmac)
593
    {
594 6
        $event = null;
595
596 6
        switch ($result) {
597 6
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
598 6
                $messageKey = 'event.message.registrationsuccessful';
599 6
                $titleKey = 'registrationResult.title.successful';
600
                break;
601 6
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
602 5
                $messageKey = 'event.message.registrationwaitlistsuccessful';
603
                $titleKey = 'registrationWaitlistResult.title.successful';
604 5
                break;
605 1
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
606 1
                $messageKey = 'event.message.registrationfailedeventexpired';
607
                $titleKey = 'registrationResult.title.failed';
608 5
                break;
609 1
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
610 1
                $messageKey = 'event.message.registrationfailedmaxparticipants';
611 5
                $titleKey = 'registrationResult.title.failed';
612
                break;
613 6
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
614 1
                $messageKey = 'event.message.registrationfailednotenabled';
615 1
                $titleKey = 'registrationResult.title.failed';
616
                break;
617 6
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
618 6
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
619
                $titleKey = 'registrationResult.title.failed';
620 6
                break;
621
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
622 6
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
623 6
                $titleKey = 'registrationResult.title.failed';
624 6
                break;
625 6
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
626 6
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
627 6
                $titleKey = 'registrationResult.title.failed';
628
                break;
629
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
630
                $messageKey = 'event.message.registrationfailedemailnotunique';
631
                $titleKey = 'registrationResult.title.failed';
632
                break;
633
            default:
634
                $messageKey = '';
635 9
                $titleKey = '';
636
        }
637 9
638
        if (!$this->hashService->validateHmac('event-' . $eventuid, $hmac)) {
639
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
640
            $titleKey = 'registrationResult.title.failed';
641
        } else {
642
            $event = $this->eventRepository->findByUid((int)$eventuid);
643
        }
644
645
        $this->view->assignMultiple([
646
            'messageKey' => $messageKey,
647
            'titleKey' => $titleKey,
648
            'event' => $event,
649
        ]);
650
    }
651
652
    /**
653
     * Confirms the registration if possible and sends e-mails to admin and user
654
     *
655
     * @param int $reguid UID of registration
656
     * @param string $hmac HMAC for parameters
657
     *
658
     * @return void
659
     */
660
    public function confirmRegistrationAction($reguid, $hmac)
661
    {
662
        $event = null;
663
664
        /* @var $registration Registration */
665
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkConfirmRegistration(
666
            $reguid,
667
            $hmac
668
        );
669
670
        if ($failed === false) {
671
            $registration->setConfirmed(true);
672
            $event = $registration->getEvent();
673
            $this->registrationRepository->update($registration);
674
675
            $messageType = MessageType::REGISTRATION_CONFIRMED;
676
            if ($registration->getWaitlist()) {
677
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
678
            }
679
680
            // Send notifications to user and admin
681
            $this->notificationService->sendUserMessage(
682
                $registration->getEvent(),
683
                $registration,
684
                $this->settings,
685
                $messageType
686
            );
687
            $this->notificationService->sendAdminMessage(
688
                $registration->getEvent(),
689
                $registration,
690
                $this->settings,
691
                $messageType
692
            );
693
694
            // Confirm registrations depending on main registration if necessary
695
            if ($registration->getAmountOfRegistrations() > 1) {
696
                $this->registrationService->confirmDependingRegistrations($registration);
697
            }
698
        }
699
700
        // Redirect to payment provider if payment/redirect is enabled
701
        $paymentPid = (int)$this->settings['paymentPid'];
702
        if (!$failed && $paymentPid > 0 && $this->registrationService->redirectPaymentEnabled($registration)) {
703
            $this->uriBuilder->reset()
704
                ->setTargetPageUid($paymentPid)
705
                ->setUseCacheHash(false);
706
            $uri =  $this->uriBuilder->uriFor(
707
                'redirect',
708
                [
709
                    'registration' => $registration,
710
                    'hmac' => $this->hashService->generateHmac('redirectAction-' . $registration->getUid())
711
                ],
712
                'Payment',
713
                'sfeventmgt',
714
                'Pipayment'
715
            );
716
            $this->redirectToUri($uri);
717
        }
718
719
        $this->view->assignMultiple([
720
            'messageKey' => $messageKey,
721
            'titleKey' => $titleKey,
722
            'event' => $event,
723
        ]);
724
    }
725
726
    /**
727
     * Cancels the registration if possible and sends e-mails to admin and user
728
     *
729
     * @param int $reguid UID of registration
730
     * @param string $hmac HMAC for parameters
731
     *
732
     * @return void
733
     */
734
    public function cancelRegistrationAction($reguid, $hmac)
735
    {
736
        $event = null;
737
738
        /* @var $registration Registration */
739
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkCancelRegistration($reguid, $hmac);
740
741
        if ($failed === false) {
742
            $event = $registration->getEvent();
743
744
            // Send notifications (must run before cancelling the registration)
745
            $this->notificationService->sendUserMessage(
746
                $registration->getEvent(),
747
                $registration,
748
                $this->settings,
749
                MessageType::REGISTRATION_CANCELLED
750
            );
751
            $this->notificationService->sendAdminMessage(
752
                $registration->getEvent(),
753
                $registration,
754
                $this->settings,
755
                MessageType::REGISTRATION_CANCELLED
756
            );
757
758
            // First cancel depending registrations
759
            if ($registration->getAmountOfRegistrations() > 1) {
760
                $this->registrationService->cancelDependingRegistrations($registration);
761
            }
762
763
            // Finally cancel registration
764
            $this->registrationRepository->remove($registration);
765
766
            // Clear cache for configured pages
767
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
768
        }
769
770
        $this->view->assignMultiple([
771
            'messageKey' => $messageKey,
772
            'titleKey' => $titleKey,
773
            'event' => $event,
774
        ]);
775
    }
776
777
    /**
778
     * Set date format for field startDate and endDate
779
     *
780
     * @return void
781
     */
782
    public function initializeSearchAction()
783
    {
784
        if ($this->settings !== null && $this->settings['search']['dateFormat']) {
785
            $this->arguments->getArgument('searchDemand')
786
                ->getPropertyMappingConfiguration()->forProperty('startDate')
787
                ->setTypeConverterOption(
788
                    DateTimeConverter::class,
789
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
790
                    $this->settings['search']['dateFormat']
791
                );
792
            $this->arguments->getArgument('searchDemand')
793
                ->getPropertyMappingConfiguration()->forProperty('endDate')
794
                ->setTypeConverterOption(
795
                    DateTimeConverter::class,
796
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
797
                    $this->settings['search']['dateFormat']
798
                );
799
        }
800
    }
801
802
    /**
803
     * Search view
804
     *
805
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
806
     * @param array $overwriteDemand OverwriteDemand
807
     *
808
     * @return void
809
     */
810
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
811
    {
812
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
813
        $eventDemand->setSearchDemand($searchDemand);
0 ignored issues
show
Bug introduced by
It seems like $searchDemand defined by parameter $searchDemand on line 810 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...
814
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
815
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
816
817
        if ($searchDemand !== null) {
818
            $searchDemand->setFields($this->settings['search']['fields']);
819
820
            if ($this->settings['search']['adjustTime'] && $searchDemand->getStartDate() !== null) {
821
                $searchDemand->getStartDate()->setTime(0, 0, 0);
822
            }
823
824
            if ($this->settings['search']['adjustTime'] && $searchDemand->getEndDate() !== null) {
825
                $searchDemand->getEndDate()->setTime(23, 59, 59);
826
            }
827
        }
828
829
        if ($this->isOverwriteDemand($overwriteDemand)) {
830
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
831
        }
832
833
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
834
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
835
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
836
837
        $events = $this->eventRepository->findDemanded($eventDemand);
838
839
        $this->view->assignMultiple([
840
            'events' => $events,
841
            'categories' => $categories,
842
            'locations' => $locations,
843
            'organisators' => $organisators,
844
            'searchDemand' => $searchDemand,
845
            'overwriteDemand' => $overwriteDemand,
846
        ]);
847
    }
848
849
    /**
850
     * Returns if a demand object can be overwritten with the given overwriteDemand array
851
     *
852
     * @param array $overwriteDemand
853
     * @return bool
854
     */
855
    protected function isOverwriteDemand($overwriteDemand)
856
    {
857
        return $this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== [];
858
    }
859
}
860