Completed
Push — master ( 17edcb...7372de )
by Torben
06:23
created

EventController::cancelRegistrationAction()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 62

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 62
ccs 0
cts 0
cp 0
rs 8.829
c 0
b 0
f 0
cc 4
nc 5
nop 2
crap 20

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
5
 *
6
 * For the full copyright and license information, please read the
7
 * LICENSE.txt file that was distributed with this source code.
8
 */
9
10
namespace DERHANSEN\SfEventMgt\Controller;
11
12
use DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand;
13
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
14
use DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand;
15
use DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand;
16
use DERHANSEN\SfEventMgt\Domain\Model\Event;
17
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
18
use DERHANSEN\SfEventMgt\Event\AfterRegistrationConfirmedEvent;
19
use DERHANSEN\SfEventMgt\Event\AfterRegistrationSavedEvent;
20
use DERHANSEN\SfEventMgt\Event\EventPidCheckFailedEvent;
21
use DERHANSEN\SfEventMgt\Event\ModifyCalendarViewVariablesEvent;
22
use DERHANSEN\SfEventMgt\Event\ModifyCancelRegistrationViewVariablesEvent;
23
use DERHANSEN\SfEventMgt\Event\ModifyConfirmRegistrationViewVariablesEvent;
24
use DERHANSEN\SfEventMgt\Event\ModifyCreateDependingRegistrationsEvent;
25
use DERHANSEN\SfEventMgt\Event\ModifyDetailViewVariablesEvent;
26
use DERHANSEN\SfEventMgt\Event\ModifyListViewVariablesEvent;
27
use DERHANSEN\SfEventMgt\Event\ModifyRegistrationViewVariablesEvent;
28
use DERHANSEN\SfEventMgt\Event\ModifySearchViewVariablesEvent;
29
use DERHANSEN\SfEventMgt\Event\WaitlistMoveUpEvent;
30
use DERHANSEN\SfEventMgt\Service\EventCacheService;
31
use DERHANSEN\SfEventMgt\Utility\MessageType;
32
use DERHANSEN\SfEventMgt\Utility\Page;
33
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
34
use TYPO3\CMS\Core\Context\Context;
35
use TYPO3\CMS\Core\Http\ImmediateResponseException;
36
use TYPO3\CMS\Core\Utility\ArrayUtility;
37
use TYPO3\CMS\Core\Utility\GeneralUtility;
38
use TYPO3\CMS\Core\Utility\HttpUtility;
39
use TYPO3\CMS\Extbase\Annotation as Extbase;
40
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
41
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
42
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
43
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
44
use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
45
use TYPO3\CMS\Fluid\View\StandaloneView;
46
use TYPO3\CMS\Frontend\Controller\ErrorController;
47
48
/**
49
 * EventController
50
 *
51
 * @author Torben Hansen <[email protected]>
52
 */
53
class EventController extends AbstractController
54
{
55
    /**
56
     * @var EventCacheService
57
     */
58
    protected $eventCacheService;
59
60
    /**
61
     * @param EventCacheService $cacheService
62
     */
63
    public function injectEventCacheService(EventCacheService $cacheService)
64
    {
65
        $this->eventCacheService = $cacheService;
66
    }
67
68
    /**
69
     * Assign contentObjectData and pageData to earch view
70
     *
71
     * @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view
72
     */
73
    protected function initializeView(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view)
74
    {
75
        $view->assign('contentObjectData', $this->configurationManager->getContentObject()->data);
76
        if (is_object($GLOBALS['TSFE'])) {
77
            $view->assign('pageData', $GLOBALS['TSFE']->page);
78
        }
79
        parent::initializeView($view);
80
    }
81
82
    /**
83
     * Initializes the current action
84
     */
85
    public function initializeAction()
86
    {
87
        $typoScriptFrontendController = $this->getTypoScriptFrontendController();
88
        if ($typoScriptFrontendController !== null) {
89
            static $cacheTagsSet = false;
90
91
            if (!$cacheTagsSet) {
92
                $typoScriptFrontendController->addCacheTags(['tx_sfeventmgt']);
93
                $cacheTagsSet = true;
94
            }
95
        }
96
    }
97
98
    /**
99
     * Creates an event demand object with the given settings
100
     *
101
     * @param array $settings The settings
102
     *
103
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
104
     */
105
    public function createEventDemandObjectFromSettings(array $settings)
106
    {
107
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand */
108
        $demand = $this->objectManager->get(EventDemand::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
109
        $demand->setDisplayMode($settings['displayMode']);
110
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
111
        $demand->setCategoryConjunction($settings['categoryConjunction']);
112
        $demand->setCategory($settings['category']);
113
        $demand->setIncludeSubcategories($settings['includeSubcategories']);
114
        $demand->setTopEventRestriction((int)$settings['topEventRestriction']);
115
        $demand->setOrderField($settings['orderField']);
116
        $demand->setOrderFieldAllowed($settings['orderFieldAllowed']);
117
        $demand->setOrderDirection($settings['orderDirection']);
118
        $demand->setQueryLimit($settings['queryLimit']);
119
        $demand->setLocation($settings['location']);
120
        $demand->setOrganisator($settings['organisator']);
121
        $demand->setSpeaker($settings['speaker']);
122
123
        return $demand;
124
    }
125
126
    /**
127
     * Creates a foreign record demand object with the given settings
128
     *
129
     * @param array $settings The settings
130
     *
131
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand
132
     */
133
    public function createForeignRecordDemandObjectFromSettings(array $settings)
134
    {
135
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand $demand */
136
        $demand = $this->objectManager->get(ForeignRecordDemand::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
137 2
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
138
        $demand->setRestrictForeignRecordsToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
139
140 2
        return $demand;
141 2
    }
142 2
143 2
    /**
144 2
     * Creates a category demand object with the given settings
145 2
     *
146 2
     * @param array $settings The settings
147 2
     *
148 2
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand
149 2
     */
150 2
    public function createCategoryDemandObjectFromSettings(array $settings)
151 2
    {
152
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand $demand */
153
        $demand = $this->objectManager->get(CategoryDemand::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
154
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
155
        $demand->setRestrictToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
156
        $demand->setCategories($settings['categoryMenu']['categories']);
157
        $demand->setIncludeSubcategories($settings['categoryMenu']['includeSubcategories']);
158
159
        return $demand;
160
    }
161
162
    /**
163
     * Hook into request processing and catch exceptions
164
     *
165
     * @param RequestInterface $request
166
     * @param ResponseInterface $response
167
     * @throws \Exception
168
     */
169
    public function processRequest(RequestInterface $request, ResponseInterface $response)
170
    {
171
        try {
172
            parent::processRequest($request, $response);
173
        } catch (\Exception $exception) {
174
            $this->handleKnownExceptionsElseThrowAgain($exception);
175
        }
176
    }
177 2
178
    /**
179
     * Handle known exceptions
180 2
     *
181 2
     * @param \Exception $exception
182 2
     * @throws \Exception
183 2
     */
184 2
    private function handleKnownExceptionsElseThrowAgain(\Exception $exception)
185 2
    {
186
        $previousException = $exception->getPrevious();
187
        $actions = ['detailAction', 'registrationAction', 'icalDownloadAction'];
188
        if (in_array($this->actionMethodName, $actions, true)
189
            && $previousException instanceof \TYPO3\CMS\Extbase\Property\Exception
190
        ) {
191
            $this->handleEventNotFoundError($this->settings);
192
        } else {
193
            throw $exception;
194
        }
195
    }
196 4
197
    /**
198 4
     * Initialize list action and set format
199 4
     */
200 4
    public function initializeListAction()
201
    {
202 4
        if (isset($this->settings['list']['format'])) {
203 4
            $this->request->setFormat($this->settings['list']['format']);
204 2
        }
205
    }
206 4
207 4
    /**
208 4
     * List view
209
     *
210
     * @param array $overwriteDemand OverwriteDemand
211
     */
212
    public function listAction(array $overwriteDemand = [])
213
    {
214
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
215
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
216
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
217
        if ($this->isOverwriteDemand($overwriteDemand)) {
218
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
219
        }
220
        $events = $this->eventRepository->findDemanded($eventDemand);
221
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
222
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
223
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
224
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
225
226
        $modifyListViewVariablesEvent = new ModifyListViewVariablesEvent(
227
            [
228
                'events' => $events,
229
                'categories' => $categories,
230 6
                'locations' => $locations,
231
                'organisators' => $organisators,
232 6
                'speakers' => $speakers,
233 6
                'overwriteDemand' => $overwriteDemand,
234 6
                'eventDemand' => $eventDemand
235 6
            ],
236 2
            $this
237 2
        );
238 6
        $this->eventDispatcher->dispatch($modifyListViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifyListViewVariablesEvent is of type object<DERHANSEN\SfEvent...ListViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
239 6
        $variables = $modifyListViewVariablesEvent->getVariables();
240 6
        $this->view->assignMultiple($variables);
241 6
242 6
        $this->eventCacheService->addPageCacheTagsByEventDemandObject($eventDemand);
243 6
    }
244 6
245 6
    /**
246
     * Calendar view
247
     *
248
     * @param array $overwriteDemand OverwriteDemand
249
     */
250
    public function calendarAction(array $overwriteDemand = [])
251
    {
252
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
253
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
254 2
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
255
        if ($this->isOverwriteDemand($overwriteDemand)) {
256 2
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
257 2
        }
258
259
        // Set month/year to demand if not given
260
        if (!$eventDemand->getMonth()) {
261
            $currentMonth = date('n');
262
            $eventDemand->setMonth($currentMonth);
263
        } else {
264
            $currentMonth = $eventDemand->getMonth();
265
        }
266 2
        if (!$eventDemand->getYear()) {
267
            $currentYear = date('Y');
268 2
            $eventDemand->setYear($currentYear);
269 2
        } else {
270
            $currentYear = $eventDemand->getYear();
271
        }
272
273
        // Set demand from calendar date range instead of month / year
274
        if ((bool)$this->settings['calendar']['includeEventsForEveryDayOfAllCalendarWeeks']) {
275
            $eventDemand = $this->changeEventDemandToFullMonthDateRange($eventDemand);
276
        }
277
278
        $events = $this->eventRepository->findDemanded($eventDemand);
279 2
        $weeks = $this->calendarService->getCalendarArray(
280
            $currentMonth,
281 2
            $currentYear,
282
            strtotime('today midnight'),
283
            (int)$this->settings['calendar']['firstDayOfWeek'],
284 2
            $events
285
        );
286 2
287 2
        $modifyCalendarViewVariablesEvent = new ModifyCalendarViewVariablesEvent(
288 2
            [
289
                'events' => $events,
290
                'weeks' => $weeks,
291
                'categories' => $this->categoryRepository->findDemanded($categoryDemand),
292
                'locations' => $this->locationRepository->findDemanded($foreignRecordDemand),
293
                'organisators' => $this->organisatorRepository->findDemanded($foreignRecordDemand),
294
                'eventDemand' => $eventDemand,
295 2
                'overwriteDemand' => $overwriteDemand,
296
                'currentPageId' => $GLOBALS['TSFE']->id,
297 2
                'firstDayOfMonth' => \DateTime::createFromFormat(
298 2
                    'd.m.Y',
299 2
                    sprintf('1.%s.%s', $currentMonth, $currentYear)
300 2
                ),
301 2
                'previousMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '-1 month'),
302 2
                'nextMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '+1 month')
303 2
            ],
304 2
            $this
305
        );
306
        $this->eventDispatcher->dispatch($modifyCalendarViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifyCalendarViewVariablesEvent is of type object<DERHANSEN\SfEvent...ndarViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
307
        $variables = $modifyCalendarViewVariablesEvent->getVariables();
308
309
        $this->view->assignMultiple($variables);
310
    }
311
312
    /**
313
     * Changes the given event demand object to select a date range for a calendar month including days of the previous
314
     * month for the first week and they days for the next month for the last week
315 22
     *
316
     * @param EventDemand $eventDemand
317 22
     * @return EventDemand
318 22
     */
319 22
    protected function changeEventDemandToFullMonthDateRange(EventDemand $eventDemand)
320
    {
321
        $calendarDateRange = $this->calendarService->getCalendarDateRange(
322 22
            $eventDemand->getMonth(),
323 8
            $eventDemand->getYear(),
324 8
            $this->settings['calendar']['firstDayOfWeek']
325 8
        );
326 8
327 8
        $eventDemand->setMonth(0);
328 8
        $eventDemand->setYear(0);
329
330 8
        $startDate = new \DateTime();
331 8
        $startDate->setTimestamp($calendarDateRange['firstDayOfCalendar']);
332 8
        $endDate = new \DateTime();
333 8
        $endDate->setTimestamp($calendarDateRange['lastDayOfCalendar']);
334
        $endDate->setTime(23, 59, 59);
335 8
336 8
        $searchDemand = new SearchDemand();
337 8
        $searchDemand->setStartDate($startDate);
338 8
        $searchDemand->setEndDate($endDate);
339 8
        $eventDemand->setSearchDemand($searchDemand);
340 8
341 8
        return $eventDemand;
342 8
    }
343
344
    /**
345 8
     * Detail view for an event
346
     *
347
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
348 8
     * @return mixed string|void
349 2
     */
350 2
    public function detailAction(Event $event = null)
351 2
    {
352 6
        $event = $this->evaluateSingleEventSetting($event);
353 6
        $event = $this->evaluateIsShortcutSetting($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->evaluateIsShortcutSetting($event) on line 353 can also be of type object; however, DERHANSEN\SfEventMgt\Con...uateIsShortcutSetting() does only seem to accept object<DERHANSEN\SfEvent...omain\Model\Event>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
354
        if (is_a($event, Event::class) && $this->settings['detail']['checkPidOfEventRecord']) {
355 8
            $event = $this->checkPidOfEventRecord($event);
0 ignored issues
show
Documentation introduced by
$event is of type null|object, but the function expects a object<DERHANSEN\SfEventMgt\Domain\Model\Event>.

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...
356
        }
357
358 8
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
359 6
            return $this->handleEventNotFoundError($this->settings);
360 6
        }
361 6
362 6
        $modifyDetailViewVariablesEvent = new ModifyDetailViewVariablesEvent(['event' => $event], $this);
363
        $this->eventDispatcher->dispatch($modifyDetailViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifyDetailViewVariablesEvent is of type object<DERHANSEN\SfEvent...tailViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
364 6
        $variables = $modifyDetailViewVariablesEvent->getVariables();
365 6
366 6
        $this->view->assignMultiple($variables);
367 6
        if ($event !== null) {
368 6
            $this->eventCacheService->addCacheTagsByEventRecords([$event]);
369
        }
370 6
    }
371 6
372
    /**
373
     * Error handling if event is not found
374 8
     *
375 2
     * @param array $settings
376 2
     * @return string
377
     */
378
    protected function handleEventNotFoundError($settings)
379 8
    {
380 8
        if (empty($settings['event']['errorHandling'])) {
381
            return null;
382 22
        }
383 2
384 2
        $configuration = GeneralUtility::trimExplode(',', $settings['event']['errorHandling'], true);
385 2
386 2
        switch ($configuration[0]) {
387
            case 'redirectToListView':
388 2
                $listPid = (int)$settings['listPid'] > 0 ? (int)$settings['listPid'] : 1;
389 2
                $this->redirect('list', null, null, null, $listPid);
390 2
                break;
391 2
            case 'pageNotFoundHandler':
392 2
                $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
393 20
                    $GLOBALS['TYPO3_REQUEST'],
394 20
                    'Event not found.'
395 20
                );
396 20
                throw new ImmediateResponseException($response, 1549896549734);
397 20
                break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
398 20
            case 'showStandaloneTemplate':
399
                if (isset($configuration[2])) {
400 22
                    $statusCode = constant(HttpUtility::class . '::HTTP_STATUS_' . $configuration[2]);
401
                    HttpUtility::setResponseCode($statusCode);
402
                }
403
                $standaloneTemplate = $this->objectManager->get(StandaloneView::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
404
                $standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($configuration[1]));
405
406
                return $standaloneTemplate->render();
407
                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...
408
            default:
409 18
        }
410
    }
411
412 18
    /**
413 2
     * Initiates the iCalendar download for the given event
414 2
     *
415 2
     * @param Event $event The event
416 16
     *
417
     * @return string|false
418
     */
419
    public function icalDownloadAction(Event $event = null)
420 16
    {
421 2
        if (is_a($event, Event::class) && $this->settings['detail']['checkPidOfEventRecord']) {
422 2
            $event = $this->checkPidOfEventRecord($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 422 can be null; however, DERHANSEN\SfEventMgt\Con...checkPidOfEventRecord() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
423 2
        }
424 14
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
425 2
            return $this->handleEventNotFoundError($this->settings);
426 2
        }
427 2
        $this->icalendarService->downloadiCalendarFile($event);
0 ignored issues
show
Bug introduced by
It seems like $event can be null; however, downloadiCalendarFile() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
428 12
        exit();
429 2
    }
430 2
431 2
    /**
432 10
     * Registration view for an event
433 2
     *
434 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
435 2
     *
436 8
     * @return mixed string|void
437 2
     */
438 2
    public function registrationAction(Event $event = null)
439 2
    {
440 6
        $event = $this->evaluateSingleEventSetting($event);
441 2
        if (is_a($event, Event::class) && $this->settings['registration']['checkPidOfEventRecord']) {
442 2
            $event = $this->checkPidOfEventRecord($event);
0 ignored issues
show
Documentation introduced by
$event is of type null|object, but the function expects a object<DERHANSEN\SfEventMgt\Domain\Model\Event>.

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...
443 2
        }
444 4
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
445 2
            return $this->handleEventNotFoundError($this->settings);
446 2
        }
447 2
        if ($event->getRestrictPaymentMethods()) {
448 2
            $paymentMethods = $this->paymentService->getRestrictedPaymentMethods($event);
0 ignored issues
show
Documentation introduced by
$event is of type object|null, but the function expects a object<DERHANSEN\SfEventMgt\Domain\Model\Event>.

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...
449 2
        } else {
450 2
            $paymentMethods = $this->paymentService->getPaymentMethods();
451 2
        }
452
453 18
        $modifyRegistrationViewVariablesEvent = new ModifyRegistrationViewVariablesEvent(
454 18
            [
455 18
                'event' => $event,
456
                'paymentMethods' => $paymentMethods,
457
            ],
458
            $this
459
        );
460
        $this->eventDispatcher->dispatch($modifyRegistrationViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifyRegistrationViewVariablesEvent is of type object<DERHANSEN\SfEvent...tionViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
461
        $variables = $modifyRegistrationViewVariablesEvent->getVariables();
462
        $this->view->assignMultiple($variables);
463
    }
464
465 6
    /**
466
     * Removes all possible spamcheck fields (which do not belong to the domain model) from arguments.
467
     */
468 6
    protected function removePossibleSpamCheckFieldsFromArguments()
469
    {
470 6
        $arguments = $this->request->getArguments();
471 4
        if (!isset($arguments['event'])) {
472 4
            return;
473
        }
474 4
475 4
        // Remove a possible honeypot field
476 2
        $honeypotField = 'hp' . (int)$arguments['event'];
477 2
        if (isset($arguments['registration'][$honeypotField])) {
478
            unset($arguments['registration'][$honeypotField]);
479
        }
480 4
481 4
        // Remove a possible challenge/response field
482 4
        if (isset($arguments['registration']['cr-response'])) {
483 4
            unset($arguments['registration']['cr-response']);
484
        }
485 4
486 4
        $this->request->setArguments($arguments);
487 4
    }
488 4
489 4
    /**
490
     * Processes incoming registrations fields and adds field values to arguments
491 4
     */
492
    protected function setRegistrationFieldValuesToArguments()
493
    {
494 4
        $arguments = $this->request->getArguments();
495 4
        if (!isset($arguments['event'])) {
496 4
            return;
497 4
        }
498
499
        /** @var Event $event */
500 6
        $event = $this->eventRepository->findByUid((int)$this->request->getArgument('event'));
501 6
        if (!$event || $event->getRegistrationFields()->count() === 0) {
502
            return;
503
        }
504
505
        $registrationMvcArgument = $this->arguments->getArgument('registration');
506
        $propertyMapping = $registrationMvcArgument->getPropertyMappingConfiguration();
507
        $propertyMapping->allowProperties('fieldValues');
508
        $propertyMapping->allowCreationForSubProperty('fieldValues');
509
        $propertyMapping->allowModificationForSubProperty('fieldValues');
510
511
        // allow creation of new objects (for validation)
512
        $propertyMapping->setTypeConverterOptions(
513
            PersistentObjectConverter::class,
514
            [
515
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true,
516
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => true
517
            ]
518 6
        );
519 6
520 6
        // Set event to registration (required for validation)
521
        $propertyMapping->allowProperties('event');
522
        $propertyMapping->allowCreationForSubProperty('event');
523
        $propertyMapping->allowModificationForSubProperty('event');
524
        $arguments['registration']['event'] = (int)$this->request->getArgument('event');
525
526
        $index = 0;
527
        foreach ((array)$arguments['registration']['fields'] as $fieldUid => $value) {
528
            // Only accept registration fields of the current event
529
            if (!in_array((int)$fieldUid, $event->getRegistrationFieldsUids(), true)) {
530 4
                continue;
531
            }
532
533 4
            // allow subvalues in new property mapper
534
            $propertyMapping->forProperty('fieldValues')->allowProperties($index);
535 4
            $propertyMapping->forProperty('fieldValues.' . $index)->allowAllProperties();
536
            $propertyMapping->allowCreationForSubProperty('fieldValues.' . $index);
537 2
            $propertyMapping->allowModificationForSubProperty('fieldValues.' . $index);
538 2
539 2
            if (is_array($value)) {
540 2
                if (empty($value)) {
541
                    $value = '';
542 2
                } else {
543 2
                    $value = json_encode($value);
544 2
                }
545 2
            }
546 2
547
            /** @var Registration\Field $field */
548 2
            $field = $this->fieldRepository->findByUid((int)$fieldUid);
549
550
            $arguments['registration']['fieldValues'][$index] = [
551 2
                'pid' => $field->getPid(),
552 2
                'value' => $value,
553 2
                'field' => (string)$fieldUid,
554
                'valueType' => $field->getValueType()
555
            ];
556 2
557
            $index++;
558
        }
559 2
560 2
        // Remove temporary "fields" field
561 4
        if (isset($arguments['registration']['fields'])) {
562 4
            $arguments = ArrayUtility::removeByPath($arguments, 'registration/fields');
563 4
        }
564
        $this->request->setArguments($arguments);
565
    }
566
567
    /**
568
     * Set date format for field dateOfBirth
569
     */
570 2
    public function initializeSaveRegistrationAction()
571
    {
572 2
        $this->arguments->getArgument('registration')
573 2
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
574 2
            ->setTypeConverterOption(
575 2
                DateTimeConverter::class,
576 2
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
577 2
                $this->settings['registration']['formatDateOfBirth']
578 2
            );
579 2
        $this->removePossibleSpamCheckFieldsFromArguments();
580 2
        $this->setRegistrationFieldValuesToArguments();
581 2
    }
582 2
583 2
    /**
584 2
     * Saves the registration
585 2
     *
586 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
587 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
588 2
     * @Extbase\Validate("DERHANSEN\SfEventMgt\Validation\Validator\RegistrationFieldValidator", param="registration")
589
     * @Extbase\Validate("DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator", param="registration")
590
     *
591
     * @return mixed string|void
592
     */
593
    public function saveRegistrationAction(Registration $registration, Event $event)
594
    {
595
        if (is_a($event, Event::class) && $this->settings['registration']['checkPidOfEventRecord']) {
596
            $event = $this->checkPidOfEventRecord($event);
597
        }
598 12
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
599
            return $this->handleEventNotFoundError($this->settings);
600 12
        }
601 12
        $autoConfirmation = (bool)$this->settings['registration']['autoConfirmation'] || $event->getEnableAutoconfirm();
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...
602 12
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
603 12
        list($success, $result) = $this->registrationService->checkRegistrationSuccess($event, $registration, $result);
0 ignored issues
show
Bug introduced by
It seems like $event can be null; however, checkRegistrationSuccess() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
604
605 12
        // Save registration if no errors
606 10
        if ($success) {
607
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
608 10
                $event,
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 596 can be null; however, DERHANSEN\SfEventMgt\Ser...sWaitlistRegistration() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
609 2
                $registration->getAmountOfRegistrations()
610 2
            );
611
            $linkValidity = (int)$this->settings['confirmation']['linkValidity'];
612 10
            if ($linkValidity === 0) {
613 2
                // Use 3600 seconds as default value if not set
614 2
                $linkValidity = 3600;
615 10
            }
616
            $confirmationUntil = new \DateTime();
617 12
            $confirmationUntil->add(new \DateInterval('PT' . $linkValidity . 'S'));
618 2
619 2
            $registration->setEvent($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 596 can be null; however, DERHANSEN\SfEventMgt\Dom...egistration::setEvent() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
620
            $registration->setPid($event->getPid());
621 12
            $registration->setRegistrationDate(new \DateTime());
622 12
            $registration->setConfirmationUntil($confirmationUntil);
623
            $registration->setLanguage($GLOBALS['TSFE']->config['config']['language']);
624 12
            $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...
625
            $registration->setWaitlist($isWaitlistRegistration);
626 12
            $registration->_setProperty('_languageUid', $this->getSysLanguageUid());
627 12
            $this->registrationRepository->add($registration);
628 12
629 12
            // Persist registration, so we have an UID
630 12
            $this->persistAll();
631 12
632
            if ($isWaitlistRegistration) {
633
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
634
            } else {
635
                $messageType = MessageType::REGISTRATION_NEW;
636
            }
637
638
            // Fix event in registration for language other than default language
639 18
            $this->registrationService->fixRegistrationEvent($registration, $event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 596 can be null; however, DERHANSEN\SfEventMgt\Ser...:fixRegistrationEvent() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
640
641 18
            // Fix language of registration fields if other than default language
642
            $this->registrationService->fixRegistationFieldValueLanguage($registration, $event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 596 can be null; however, DERHANSEN\SfEventMgt\Ser...ionFieldValueLanguage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
643
644
            $this->eventDispatcher->dispatch(new AfterRegistrationSavedEvent($registration, $this));
0 ignored issues
show
Documentation introduced by
new \DERHANSEN\SfEventMg...t($registration, $this) is of type object<DERHANSEN\SfEvent...RegistrationSavedEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
645
646
            // Send notifications to user and admin if confirmation link should be sent
647
            if (!$autoConfirmation) {
648
                $this->notificationService->sendUserMessage(
649
                    $event,
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 596 can be null; however, DERHANSEN\SfEventMgt\Ser...vice::sendUserMessage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
650
                    $registration,
651
                    $this->settings,
652
                    $messageType
653
                );
654
                $this->notificationService->sendAdminMessage(
655
                    $event,
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 596 can be null; however, DERHANSEN\SfEventMgt\Ser...ice::sendAdminMessage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
656
                    $registration,
657
                    $this->settings,
658
                    $messageType
659
                );
660
            }
661
662
            // Create given amount of registrations if necessary
663
            $modifyCreateDependingRegistrationsEvent = new ModifyCreateDependingRegistrationsEvent(
664
                $registration,
665
                ($registration->getAmountOfRegistrations() > 1),
666
                $this
667
            );
668
            $this->eventDispatcher->dispatch($modifyCreateDependingRegistrationsEvent);
0 ignored issues
show
Documentation introduced by
$modifyCreateDependingRegistrationsEvent is of type object<DERHANSEN\SfEvent...dingRegistrationsEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
669
            $createDependingRegistrations = $modifyCreateDependingRegistrationsEvent->getCreateDependingRegistrations();
670
            if ($createDependingRegistrations) {
671
                $this->registrationService->createDependingRegistrations($registration);
672
            }
673
674
            // Flush page cache for event, since new registration has been added
675
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
676
        }
677
678
        if ($autoConfirmation && $success) {
679
            $this->redirect(
680
                'confirmRegistration',
681
                null,
682
                null,
683
                [
684
                    'reguid' => $registration->getUid(),
685
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid())
686
                ]
687
            );
688
        } else {
689
            $this->redirect(
690
                'saveRegistrationResult',
691
                null,
692
                null,
693
                [
694
                    'result' => $result,
695
                    'eventuid' => $event->getUid(),
696
                    'hmac' => $this->hashService->generateHmac('event-' . $event->getUid())
697
                ]
698
            );
699
        }
700
    }
701
702
    /**
703
     * Shows the result of the saveRegistrationAction
704
     *
705
     * @param int $result Result
706
     * @param int $eventuid
707
     * @param string $hmac
708
     */
709
    public function saveRegistrationResultAction($result, $eventuid, $hmac)
710
    {
711
        $event = null;
712
713
        switch ($result) {
714
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
715
                $messageKey = 'event.message.registrationsuccessful';
716
                $titleKey = 'registrationResult.title.successful';
717
                break;
718
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
719
                $messageKey = 'event.message.registrationwaitlistsuccessful';
720
                $titleKey = 'registrationWaitlistResult.title.successful';
721
                break;
722
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
723
                $messageKey = 'event.message.registrationfailedeventexpired';
724
                $titleKey = 'registrationResult.title.failed';
725
                break;
726
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
727
                $messageKey = 'event.message.registrationfailedmaxparticipants';
728
                $titleKey = 'registrationResult.title.failed';
729
                break;
730
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
731
                $messageKey = 'event.message.registrationfailednotenabled';
732
                $titleKey = 'registrationResult.title.failed';
733
                break;
734
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
735
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
736
                $titleKey = 'registrationResult.title.failed';
737
                break;
738
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
739
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
740
                $titleKey = 'registrationResult.title.failed';
741
                break;
742
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
743
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
744
                $titleKey = 'registrationResult.title.failed';
745
                break;
746
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
747
                $messageKey = 'event.message.registrationfailedemailnotunique';
748
                $titleKey = 'registrationResult.title.failed';
749
                break;
750
            default:
751
                $messageKey = '';
752
                $titleKey = '';
753
        }
754
755
        if (!$this->hashService->validateHmac('event-' . $eventuid, $hmac)) {
756
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
757
            $titleKey = 'registrationResult.title.failed';
758
        } else {
759
            $event = $this->eventRepository->findByUid((int)$eventuid);
760
        }
761
762
        $this->view->assignMultiple([
763
            'messageKey' => $messageKey,
764
            'titleKey' => $titleKey,
765
            'event' => $event,
766
        ]);
767
    }
768
769
    /**
770
     * Confirms the registration if possible and sends emails to admin and user
771
     *
772
     * @param int $reguid UID of registration
773
     * @param string $hmac HMAC for parameters
774
     */
775
    public function confirmRegistrationAction($reguid, $hmac)
776
    {
777
        $event = null;
778
779
        /* @var $registration Registration */
780
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkConfirmRegistration(
781
            $reguid,
782
            $hmac
783
        );
784
785
        if ($failed === false) {
786
            $registration->setConfirmed(true);
787
            $event = $registration->getEvent();
788
            $this->registrationRepository->update($registration);
789
790
            $this->eventDispatcher->dispatch(new AfterRegistrationConfirmedEvent($registration, $this));
0 ignored issues
show
Documentation introduced by
new \DERHANSEN\SfEventMg...t($registration, $this) is of type object<DERHANSEN\SfEvent...strationConfirmedEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
791
792
            $messageType = MessageType::REGISTRATION_CONFIRMED;
793
            if ($registration->getWaitlist()) {
794
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
795
            }
796
797
            // Send notifications to user and admin
798
            $this->notificationService->sendUserMessage(
799
                $registration->getEvent(),
800
                $registration,
801
                $this->settings,
802
                $messageType
803
            );
804
            $this->notificationService->sendAdminMessage(
805
                $registration->getEvent(),
806
                $registration,
807
                $this->settings,
808
                $messageType
809
            );
810
811
            // Confirm registrations depending on main registration if necessary
812
            if ($registration->getAmountOfRegistrations() > 1) {
813
                $this->registrationService->confirmDependingRegistrations($registration);
814
            }
815
        }
816
817
        // Redirect to payment provider if payment/redirect is enabled
818
        $paymentPid = (int)$this->settings['paymentPid'];
819
        if (!$failed && $paymentPid > 0 && $this->registrationService->redirectPaymentEnabled($registration)) {
820
            $this->uriBuilder->reset()
821
                ->setTargetPageUid($paymentPid);
822
            $uri = $this->uriBuilder->uriFor(
823
                'redirect',
824
                [
825
                    'registration' => $registration,
826
                    'hmac' => $this->hashService->generateHmac('redirectAction-' . $registration->getUid())
827
                ],
828
                'Payment',
829
                'sfeventmgt',
830
                'Pipayment'
831
            );
832
            $this->redirectToUri($uri);
833
        }
834
835
        $modifyConfirmRegistrationViewVariablesEvent = new ModifyConfirmRegistrationViewVariablesEvent(
836
            [
837
                'failed' => $failed,
838
                'messageKey' => $messageKey,
839
                'titleKey' => $titleKey,
840
                'event' => $event,
841
                'registration' => $registration,
842
            ],
843
            $this
844
        );
845
        $this->eventDispatcher->dispatch($modifyConfirmRegistrationViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifyConfirmRegistrationViewVariablesEvent is of type object<DERHANSEN\SfEvent...tionViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
846
        $variables = $modifyConfirmRegistrationViewVariablesEvent->getVariables();
847
        $this->view->assignMultiple($variables);
848
    }
849
850
    /**
851
     * Cancels the registration if possible and sends emails to admin and user
852
     *
853
     * @param int $reguid UID of registration
854
     * @param string $hmac HMAC for parameters
855
     */
856
    public function cancelRegistrationAction($reguid, $hmac)
857
    {
858
        $event = null;
859
860
        /* @var $registration Registration */
861
        list($failed, $registration, $messageKey, $titleKey) =
862
            $this->registrationService->checkCancelRegistration($reguid, $hmac);
863
864
        if ($failed === false) {
865
            $event = $registration->getEvent();
866
867
            // Send notifications (must run before cancelling the registration)
868
            $this->notificationService->sendUserMessage(
869
                $registration->getEvent(),
870
                $registration,
871
                $this->settings,
872
                MessageType::REGISTRATION_CANCELLED
873
            );
874
            $this->notificationService->sendAdminMessage(
875
                $registration->getEvent(),
876
                $registration,
877
                $this->settings,
878
                MessageType::REGISTRATION_CANCELLED
879
            );
880
881
            // First cancel depending registrations
882
            if ($registration->getAmountOfRegistrations() > 1) {
883
                $this->registrationService->cancelDependingRegistrations($registration);
884
            }
885
886
            // Finally cancel registration
887
            $this->registrationRepository->remove($registration);
888
889
            // Persist changes, so following functions can work with $event properties (e.g. amount of registrations)
890
            $this->persistAll();
891
892
            // Dispatch event, so waitlist registrations can be moved up and default move up process can be stopped
893
            $waitlistMoveUpEvent = new WaitlistMoveUpEvent($event, $this, true);
894
            $this->eventDispatcher->dispatch($waitlistMoveUpEvent);
0 ignored issues
show
Documentation introduced by
$waitlistMoveUpEvent is of type object<DERHANSEN\SfEvent...nt\WaitlistMoveUpEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
895
896
            // Move up waitlist registrations if configured on event basis and if not disabled by $waitlistMoveUpEvent
897
            if ($waitlistMoveUpEvent->getProcessDefaultMoveUp()) {
898
                $this->registrationService->moveUpWaitlistRegistrations($event, $this->settings);
899
            }
900
901
            // Flush page cache for event, since amount of registrations has changed
902
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
903
        }
904
905
        $modifyCancelRegistrationViewVariablesEvent = new ModifyCancelRegistrationViewVariablesEvent(
906
            [
907
                'failed' => $failed,
908
                'messageKey' => $messageKey,
909
                'titleKey' => $titleKey,
910
                'event' => $event,
911
            ],
912
            $this
913
        );
914
        $this->eventDispatcher->dispatch($modifyCancelRegistrationViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifyCancelRegistrationViewVariablesEvent is of type object<DERHANSEN\SfEvent...tionViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
915
        $variables = $modifyCancelRegistrationViewVariablesEvent->getVariables();
916
        $this->view->assignMultiple($variables);
917
    }
918
919
    /**
920
     * Set date format for field startDate and endDate
921
     */
922
    public function initializeSearchAction()
923
    {
924
        if ($this->settings !== null && $this->settings['search']['dateFormat']) {
925
            $this->arguments->getArgument('searchDemand')
926
                ->getPropertyMappingConfiguration()->forProperty('startDate')
927
                ->setTypeConverterOption(
928
                    DateTimeConverter::class,
929
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
930
                    $this->settings['search']['dateFormat']
931
                );
932
            $this->arguments->getArgument('searchDemand')
933
                ->getPropertyMappingConfiguration()->forProperty('endDate')
934
                ->setTypeConverterOption(
935
                    DateTimeConverter::class,
936
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
937
                    $this->settings['search']['dateFormat']
938
                );
939
        }
940
        if ($this->arguments->hasArgument('searchDemand')) {
941
            $propertyMappingConfiguration = $this->arguments->getArgument('searchDemand')
942
                ->getPropertyMappingConfiguration();
943
            $propertyMappingConfiguration->allowAllProperties();
944
            $propertyMappingConfiguration->setTypeConverterOption(
945
                PersistentObjectConverter::class,
946
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED,
947
                true
948
            );
949
        }
950
    }
951
952
    /**
953
     * Search view
954
     *
955
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
956
     * @param array $overwriteDemand OverwriteDemand
957
     */
958
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
959
    {
960
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
961
        $eventDemand->setSearchDemand($searchDemand);
0 ignored issues
show
Bug introduced by
It seems like $searchDemand defined by parameter $searchDemand on line 958 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...
962
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
963
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
964
965
        if ($searchDemand !== null) {
966
            $searchDemand->setFields($this->settings['search']['fields']);
967
968
            if ($this->settings['search']['adjustTime'] && $searchDemand->getStartDate() !== null) {
969
                $searchDemand->getStartDate()->setTime(0, 0, 0);
970
            }
971
972
            if ($this->settings['search']['adjustTime'] && $searchDemand->getEndDate() !== null) {
973
                $searchDemand->getEndDate()->setTime(23, 59, 59);
974
            }
975
        }
976
977
        if ($this->isOverwriteDemand($overwriteDemand)) {
978
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
979
        }
980
981
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
982
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
983
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
984
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
985
        $events = $this->eventRepository->findDemanded($eventDemand);
986
987
        $modifySearchViewVariablesEvent = new ModifySearchViewVariablesEvent(
988
            [
989
                'events' => $events,
990
                'categories' => $categories,
991
                'locations' => $locations,
992
                'organisators' => $organisators,
993
                'speakers' => $speakers,
994
                'searchDemand' => $searchDemand,
995
                'overwriteDemand' => $overwriteDemand,
996
            ],
997
            $this
998
        );
999
        $this->eventDispatcher->dispatch($modifySearchViewVariablesEvent);
0 ignored issues
show
Documentation introduced by
$modifySearchViewVariablesEvent is of type object<DERHANSEN\SfEvent...archViewVariablesEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
1000
        $variables = $modifySearchViewVariablesEvent->getVariables();
1001
        $this->view->assignMultiple($variables);
1002
    }
1003
1004
    /**
1005
     * Returns if a demand object can be overwritten with the given overwriteDemand array
1006
     *
1007
     * @param array $overwriteDemand
1008
     * @return bool
1009
     */
1010
    protected function isOverwriteDemand($overwriteDemand)
1011
    {
1012
        return $this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== [];
1013
    }
1014
1015
    /**
1016
     * If no event is given and the singleEvent setting is set, the configured single event is returned
1017
     *
1018
     * @param Event|null $event
1019
     * @return Event|null
1020
     */
1021
    protected function evaluateSingleEventSetting($event)
1022
    {
1023
        if ($event === null && (int)$this->settings['singleEvent'] > 0) {
1024
            $event = $this->eventRepository->findByUid((int)$this->settings['singleEvent']);
1025
        }
1026
1027
        return $event;
1028
    }
1029
1030
    /**
1031
     * If no event is given and the isShortcut setting is set, the event is displayed using the "Insert Record"
1032
     * content element and should be loaded from contect object data
1033
     *
1034
     * @param Event|null $event
1035
     * @return Event|null
1036
     */
1037
    protected function evaluateIsShortcutSetting($event)
1038
    {
1039
        if ($event === null && (bool)$this->settings['detail']['isShortcut']) {
1040
            $eventRawData = $this->configurationManager->getContentObject()->data;
1041
            $event = $this->eventRepository->findByUid($eventRawData['uid']);
1042
        }
1043
1044
        return $event;
1045
    }
1046
1047
    /**
1048
     * Checks if the event pid could be found in the storagePage settings of the detail plugin and
1049
     * if the pid could not be found it return null instead of the event object.
1050
     *
1051
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
1052
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Event|null
1053
     */
1054
    protected function checkPidOfEventRecord(Event $event)
1055
    {
1056
        $allowedStoragePages = GeneralUtility::trimExplode(
1057
            ',',
1058
            Page::extendPidListByChildren(
1059
                $this->settings['storagePage'],
1060
                $this->settings['recursive']
1061
            ),
1062
            true
1063
        );
1064
        if (count($allowedStoragePages) > 0 && !in_array($event->getPid(), $allowedStoragePages)) {
1065
            $this->eventDispatcher->dispatch(new EventPidCheckFailedEvent($event, $this));
0 ignored issues
show
Documentation introduced by
new \DERHANSEN\SfEventMg...ledEvent($event, $this) is of type object<DERHANSEN\SfEvent...entPidCheckFailedEvent>, but the function expects a object<Psr\EventDispatcher\object>.

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...
1066
            $event = null;
1067
        }
1068
1069
        return $event;
1070
    }
1071
1072
    /**
1073
     * Calls persistAll() of the persistenceManager
1074
     */
1075
    protected function persistAll()
1076
    {
1077
        $this->objectManager->get(PersistenceManager::class)->persistAll();
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1078
    }
1079
1080
    /**
1081
     * Returns the current sys_language_uid
1082
     *
1083
     * @return int
1084
     */
1085
    protected function getSysLanguageUid()
1086
    {
1087
        $languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
1088
1089
        return $languageAspect->getId();
1090
    }
1091
}
1092