Completed
Push — master ( c18e86...b01b7f )
by Torben
04:02
created

EventController::evaluateIsShortcutSetting()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 0
cts 0
cp 0
rs 9.9666
c 0
b 0
f 0
cc 3
nc 2
nop 1
crap 12
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\Service\EventCacheService;
18
use DERHANSEN\SfEventMgt\Utility\MessageType;
19
use DERHANSEN\SfEventMgt\Utility\Page;
20
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
21
use TYPO3\CMS\Core\Utility\ArrayUtility;
22
use TYPO3\CMS\Core\Utility\GeneralUtility;
23
use TYPO3\CMS\Core\Utility\HttpUtility;
24
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
25
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
26
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
27
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
28
use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
29
use TYPO3\CMS\Fluid\View\StandaloneView;
30
31
/**
32
 * EventController
33
 *
34
 * @author Torben Hansen <[email protected]>
35
 */
36
class EventController extends AbstractController
37
{
38
    /**
39
     * @var EventCacheService
40
     */
41
    protected $eventCacheService = null;
42
43
    /**
44
     * @param EventCacheService $cacheService
45
     */
46
    public function injectEventCacheService(EventCacheService $cacheService)
47
    {
48
        $this->eventCacheService = $cacheService;
49
    }
50
51
    /**
52
     * Assign contentObjectData and pageData to earch view
53
     *
54
     * @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view
55
     */
56
    protected function initializeView(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view)
57
    {
58
        $view->assign('contentObjectData', $this->configurationManager->getContentObject()->data);
59
        if (is_object($GLOBALS['TSFE'])) {
60
            $view->assign('pageData', $GLOBALS['TSFE']->page);
61
        }
62
        parent::initializeView($view);
63
    }
64
65
    /**
66
     * Initializes the current action
67
     */
68
    public function initializeAction()
69
    {
70
        $typoScriptFrontendController = $this->getTypoScriptFrontendController();
71
        if ($typoScriptFrontendController !== null) {
72
            static $cacheTagsSet = false;
73
74
            if (!$cacheTagsSet) {
75
                $typoScriptFrontendController->addCacheTags(['tx_sfeventmgt']);
76
                $cacheTagsSet = true;
77
            }
78
        }
79
    }
80
81
    /**
82
     * Creates an event demand object with the given settings
83
     *
84
     * @param array $settings The settings
85
     *
86
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
87
     */
88
    public function createEventDemandObjectFromSettings(array $settings)
89
    {
90
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand */
91
        $demand = $this->objectManager->get(EventDemand::class);
92
        $demand->setDisplayMode($settings['displayMode']);
93
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
94
        $demand->setCategoryConjunction($settings['categoryConjunction']);
95
        $demand->setCategory($settings['category']);
96
        $demand->setIncludeSubcategories($settings['includeSubcategories']);
97
        $demand->setTopEventRestriction((int)$settings['topEventRestriction']);
98
        $demand->setOrderField($settings['orderField']);
99
        $demand->setOrderFieldAllowed($settings['orderFieldAllowed']);
100
        $demand->setOrderDirection($settings['orderDirection']);
101
        $demand->setQueryLimit($settings['queryLimit']);
102
        $demand->setLocation($settings['location']);
103
        $demand->setOrganisator($settings['organisator']);
104
        $demand->setSpeaker($settings['speaker']);
105
106
        return $demand;
107
    }
108
109
    /**
110
     * Creates a foreign record demand object with the given settings
111
     *
112
     * @param array $settings The settings
113
     *
114
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand
115
     */
116
    public function createForeignRecordDemandObjectFromSettings(array $settings)
117
    {
118
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand $demand */
119
        $demand = $this->objectManager->get(ForeignRecordDemand::class);
120
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
121
        $demand->setRestrictForeignRecordsToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
122
123
        return $demand;
124
    }
125
126
    /**
127
     * Creates a category demand object with the given settings
128
     *
129
     * @param array $settings The settings
130
     *
131
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand
132
     */
133
    public function createCategoryDemandObjectFromSettings(array $settings)
134
    {
135
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand $demand */
136
        $demand = $this->objectManager->get(CategoryDemand::class);
137 2
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
138
        $demand->setRestrictToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
139
        $demand->setCategories($settings['categoryMenu']['categories']);
140 2
        $demand->setIncludeSubcategories($settings['categoryMenu']['includeSubcategories']);
141 2
142 2
        return $demand;
143 2
    }
144 2
145 2
    /**
146 2
     * Hook into request processing and catch exceptions
147 2
     *
148 2
     * @param RequestInterface $request
149 2
     * @param ResponseInterface $response
150 2
     * @throws \Exception
151 2
     */
152
    public function processRequest(RequestInterface $request, ResponseInterface $response)
153
    {
154
        try {
155
            parent::processRequest($request, $response);
156
        } catch (\Exception $exception) {
157
            $this->handleKnownExceptionsElseThrowAgain($exception);
158
        }
159
    }
160
161
    /**
162
     * Handle known exceptions
163
     *
164
     * @param \Exception $exception
165
     * @throws \Exception
166
     */
167
    private function handleKnownExceptionsElseThrowAgain(\Exception $exception)
168
    {
169
        $previousException = $exception->getPrevious();
170
        $actions = ['detailAction', 'registrationAction', 'icalDownloadAction'];
171
        if (in_array($this->actionMethodName, $actions, true)
172
            && $previousException instanceof \TYPO3\CMS\Extbase\Property\Exception
173
        ) {
174
            $this->handleEventNotFoundError($this->settings);
175
        } else {
176
            throw $exception;
177 2
        }
178
    }
179
180 2
    /**
181 2
     * Initialize list action and set format
182 2
     *
183 2
     * @return void
184 2
     */
185 2
    public function initializeListAction()
186
    {
187
        if (isset($this->settings['list']['format'])) {
188
            $this->request->setFormat($this->settings['list']['format']);
189
        }
190
    }
191
192
    /**
193
     * List view
194
     *
195
     * @param array $overwriteDemand OverwriteDemand
196 4
     *
197
     * @return void
198 4
     */
199 4
    public function listAction(array $overwriteDemand = [])
200 4
    {
201
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
202 4
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
203 4
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
204 2
        if ($this->isOverwriteDemand($overwriteDemand)) {
205
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
206 4
        }
207 4
        $events = $this->eventRepository->findDemanded($eventDemand);
208 4
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
209
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
210
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
211
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
212
213
        $values = [
214
            'events' => $events,
215
            'categories' => $categories,
216
            'locations' => $locations,
217
            'organisators' => $organisators,
218
            'speakers' => $speakers,
219
            'overwriteDemand' => $overwriteDemand,
220
            'eventDemand' => $eventDemand
221
        ];
222
223
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
224
        $this->view->assignMultiple($values);
225
226
        $this->eventCacheService->addPageCacheTagsByEventDemandObject($eventDemand);
227
    }
228
229
    /**
230 6
     * Calendar view
231
     *
232 6
     * @param array $overwriteDemand OverwriteDemand
233 6
     *
234 6
     * @return void
235 6
     */
236 2
    public function calendarAction(array $overwriteDemand = [])
237 2
    {
238 6
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
239 6
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
240 6
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
241 6
        if ($this->isOverwriteDemand($overwriteDemand)) {
242 6
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
243 6
        }
244 6
245 6
        // Set month/year to demand if not given
246
        if (!$eventDemand->getMonth()) {
247
            $currentMonth = date('n');
248
            $eventDemand->setMonth($currentMonth);
249
        } else {
250
            $currentMonth = $eventDemand->getMonth();
251
        }
252
        if (!$eventDemand->getYear()) {
253
            $currentYear = date('Y');
254 2
            $eventDemand->setYear($currentYear);
255
        } else {
256 2
            $currentYear = $eventDemand->getYear();
257 2
        }
258
259
        // Set demand from calendar date range instead of month / year
260
        if ((bool)$this->settings['calendar']['includeEventsForEveryDayOfAllCalendarWeeks']) {
261
            $eventDemand = $this->changeEventDemandToFullMonthDateRange($eventDemand);
262
        }
263
264
        $events = $this->eventRepository->findDemanded($eventDemand);
265
        $weeks = $this->calendarService->getCalendarArray(
266 2
            $currentMonth,
267
            $currentYear,
268 2
            strtotime('today midnight'),
269 2
            (int)$this->settings['calendar']['firstDayOfWeek'],
270
            $events
271
        );
272
273
        $values = [
274
            'events' => $events,
275
            'weeks' => $weeks,
276
            'categories' => $this->categoryRepository->findDemanded($categoryDemand),
277
            'locations' => $this->locationRepository->findDemanded($foreignRecordDemand),
278
            'organisators' => $this->organisatorRepository->findDemanded($foreignRecordDemand),
279 2
            'eventDemand' => $eventDemand,
280
            'overwriteDemand' => $overwriteDemand,
281 2
            'currentPageId' => $GLOBALS['TSFE']->id,
282
            'firstDayOfMonth' => \DateTime::createFromFormat('d.m.Y', sprintf('1.%s.%s', $currentMonth, $currentYear)),
283
            'previousMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '-1 month'),
284 2
            'nextMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '+1 month')
285
        ];
286 2
287 2
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
288 2
        $this->view->assignMultiple($values);
289
    }
290
291
    /**
292
     * Changes the given event demand object to select a date range for a calendar month including days of the previous
293
     * month for the first week and they days for the next month for the last week
294
     *
295 2
     * @param EventDemand $eventDemand
296
     * @return EventDemand
297 2
     */
298 2
    protected function changeEventDemandToFullMonthDateRange(EventDemand $eventDemand)
299 2
    {
300 2
        $calendarDateRange = $this->calendarService->getCalendarDateRange(
301 2
            $eventDemand->getMonth(),
302 2
            $eventDemand->getYear(),
303 2
            $this->settings['calendar']['firstDayOfWeek']
304 2
        );
305
306
        $eventDemand->setMonth(0);
307
        $eventDemand->setYear(0);
308
309
        $startDate = new \DateTime();
310
        $startDate->setTimestamp($calendarDateRange['firstDayOfCalendar']);
311
        $endDate = new \DateTime();
312
        $endDate->setTimestamp($calendarDateRange['lastDayOfCalendar']);
313
        $endDate->setTime(23, 59, 59);
314
315 22
        $searchDemand = new SearchDemand();
316
        $searchDemand->setStartDate($startDate);
317 22
        $searchDemand->setEndDate($endDate);
318 22
        $eventDemand->setSearchDemand($searchDemand);
319 22
320
        return $eventDemand;
321
    }
322 22
323 8
    /**
324 8
     * Detail view for an event
325 8
     *
326 8
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
327 8
     * @return mixed string|void
328 8
     */
329
    public function detailAction(Event $event = null)
330 8
    {
331 8
        $event = $this->evaluateSingleEventSetting($event);
332 8
        $event = $this->evaluateIsShortcutSetting($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->evaluateIsShortcutSetting($event) on line 332 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...
333 8
        if (is_a($event, Event::class) && $this->settings['detail']['checkPidOfEventRecord']) {
334
            $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...
335 8
        }
336 8
337 8
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
338 8
            return $this->handleEventNotFoundError($this->settings);
339 8
        }
340 8
        $values = ['event' => $event];
341 8
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
342 8
        $this->view->assignMultiple($values);
343
        if ($event !== null) {
344
            $this->eventCacheService->addCacheTagsByEventRecords([$event]);
345 8
        }
346
    }
347
348 8
    /**
349 2
     * Error handling if event is not found
350 2
     *
351 2
     * @param array $settings
352 6
     * @return string
353 6
     */
354
    protected function handleEventNotFoundError($settings)
355 8
    {
356
        if (empty($settings['event']['errorHandling'])) {
357
            return null;
358 8
        }
359 6
360 6
        $configuration = GeneralUtility::trimExplode(',', $settings['event']['errorHandling'], true);
361 6
362 6
        switch ($configuration[0]) {
363
            case 'redirectToListView':
364 6
                $listPid = (int)$settings['listPid'] > 0 ? (int)$settings['listPid'] : 1;
365 6
                $this->redirect('list', null, null, null, $listPid);
366 6
                break;
367 6
            case 'pageNotFoundHandler':
368 6
                $GLOBALS['TSFE']->pageNotFoundAndExit('Event not found.');
369
                break;
370 6
            case 'showStandaloneTemplate':
371 6
                if (isset($configuration[2])) {
372
                    $statusCode = constant(HttpUtility::class . '::HTTP_STATUS_' . $configuration[2]);
373
                    HttpUtility::setResponseCode($statusCode);
374 8
                }
375 2
                $standaloneTemplate = $this->objectManager->get(StandaloneView::class);
376 2
                $standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($configuration[1]));
377
378
                return $standaloneTemplate->render();
379 8
                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...
380 8
            default:
381
        }
382 22
    }
383 2
384 2
    /**
385 2
     * Initiates the iCalendar download for the given event
386 2
     *
387
     * @param Event $event The event
388 2
     *
389 2
     * @return string|false
390 2
     */
391 2
    public function icalDownloadAction(Event $event = null)
392 2
    {
393 20
        if (is_a($event, Event::class) && $this->settings['detail']['checkPidOfEventRecord']) {
394 20
            $event = $this->checkPidOfEventRecord($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 394 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...
395 20
        }
396 20
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
397 20
            return $this->handleEventNotFoundError($this->settings);
398 20
        }
399
        $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...
400 22
        exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method icalDownloadAction() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
401
    }
402
403
    /**
404
     * Registration view for an event
405
     *
406
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
407
     *
408
     * @return mixed string|void
409 18
     */
410
    public function registrationAction(Event $event = null)
411
    {
412 18
        $event = $this->evaluateSingleEventSetting($event);
413 2
        if (is_a($event, Event::class) && $this->settings['registration']['checkPidOfEventRecord']) {
414 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...
415 2
        }
416 16
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
417
            return $this->handleEventNotFoundError($this->settings);
418
        }
419
        if ($event->getRestrictPaymentMethods()) {
420 16
            $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...
421 2
        } else {
422 2
            $paymentMethods = $this->paymentService->getPaymentMethods();
423 2
        }
424 14
425 2
        $values = [
426 2
            'event' => $event,
427 2
            'paymentMethods' => $paymentMethods,
428 12
        ];
429 2
430 2
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
431 2
        $this->view->assignMultiple($values);
432 10
    }
433 2
434 2
    /**
435 2
     * Processes incoming registrations fields and adds field values to arguments
436 8
     *
437 2
     * @return void
438 2
     */
439 2
    protected function setRegistrationFieldValuesToArguments()
440 6
    {
441 2
        $arguments = $this->request->getArguments();
442 2
        if (!isset($arguments['event'])) {
443 2
            return;
444 4
        }
445 2
446 2
        /** @var Event $event */
447 2
        $event = $this->eventRepository->findByUid((int)$this->request->getArgument('event'));
448 2
        if (!$event || $event->getRegistrationFields()->count() === 0) {
449 2
            return;
450 2
        }
451 2
452
        $registrationMvcArgument = $this->arguments->getArgument('registration');
453 18
        $propertyMapping = $registrationMvcArgument->getPropertyMappingConfiguration();
454 18
        $propertyMapping->allowProperties('fieldValues');
455 18
        $propertyMapping->allowCreationForSubProperty('fieldValues');
456
        $propertyMapping->allowModificationForSubProperty('fieldValues');
457
458
        // allow creation of new objects (for validation)
459
        $propertyMapping->setTypeConverterOptions(
460
            PersistentObjectConverter::class,
461
            [
462
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true,
463
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => true
464
            ]
465 6
        );
466
467
        // Set event to registration (required for validation)
468 6
        $propertyMapping->allowProperties('event');
469
        $propertyMapping->allowCreationForSubProperty('event');
470 6
        $propertyMapping->allowModificationForSubProperty('event');
471 4
        $arguments['registration']['event'] = (int)$this->request->getArgument('event');
472 4
473
        $index = 0;
474 4
        foreach ((array)$arguments['registration']['fields'] as $fieldUid => $value) {
475 4
            // Only accept registration fields of the current event
476 2
            if (!in_array((int)$fieldUid, $event->getRegistrationFieldsUids(), true)) {
477 2
                continue;
478
            }
479
480 4
            // allow subvalues in new property mapper
481 4
            $propertyMapping->forProperty('fieldValues')->allowProperties($index);
482 4
            $propertyMapping->forProperty('fieldValues.' . $index)->allowAllProperties();
483 4
            $propertyMapping->allowCreationForSubProperty('fieldValues.' . $index);
484
            $propertyMapping->allowModificationForSubProperty('fieldValues.' . $index);
485 4
486 4
            if (is_array($value)) {
487 4
                if (empty($value)) {
488 4
                    $value = '';
489 4
                } else {
490
                    $value = json_encode($value);
491 4
                }
492
            }
493
494 4
            /** @var Registration\Field $field */
495 4
            $field = $this->fieldRepository->findByUid((int)$fieldUid);
496 4
497 4
            $arguments['registration']['fieldValues'][$index] = [
498
                'pid' => $field->getPid(),
499
                'value' => $value,
500 6
                'field' => strval($fieldUid),
501 6
                'valueType' => $field->getValueType()
502
            ];
503
504
            $index++;
505
        }
506
507
        // Remove temporary "fields" field
508
        if (isset($arguments['registration']['fields'])) {
509
            $arguments = ArrayUtility::removeByPath($arguments, 'registration/fields');
510
        }
511
        $this->request->setArguments($arguments);
512
    }
513
514
    /**
515
     * Set date format for field dateOfBirth
516
     *
517
     * @return void
518 6
     */
519 6
    public function initializeSaveRegistrationAction()
520 6
    {
521
        $this->arguments->getArgument('registration')
522
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
523
            ->setTypeConverterOption(
524
                DateTimeConverter::class,
525
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
526
                $this->settings['registration']['formatDateOfBirth']
527
            );
528
        $this->setRegistrationFieldValuesToArguments();
529
    }
530 4
531
    /**
532
     * Saves the registration
533 4
     *
534
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
535 4
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
536
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationFieldValidator
537 2
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator
538 2
     *
539 2
     * @return mixed string|void
540 2
     */
541
    public function saveRegistrationAction(Registration $registration, Event $event)
542 2
    {
543 2
        if (is_a($event, Event::class) && $this->settings['registration']['checkPidOfEventRecord']) {
544 2
            $event = $this->checkPidOfEventRecord($event);
545 2
        }
546 2
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
547
            return $this->handleEventNotFoundError($this->settings);
548 2
        }
549
        $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...
550
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
551 2
        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...
552 2
553 2
        // Save registration if no errors
554
        if ($success) {
555
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
556 2
                $event,
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 544 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...
557
                $registration->getAmountOfRegistrations()
558
            );
559 2
            $linkValidity = (int)$this->settings['confirmation']['linkValidity'];
560 2
            if ($linkValidity === 0) {
561 4
                // Use 3600 seconds as default value if not set
562 4
                $linkValidity = 3600;
563 4
            }
564
            $confirmationUntil = new \DateTime();
565
            $confirmationUntil->add(new \DateInterval('PT' . $linkValidity . 'S'));
566
567
            $registration->setEvent($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 544 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...
568
            $registration->setPid($event->getPid());
569
            $registration->setConfirmationUntil($confirmationUntil);
570 2
            $registration->setLanguage($GLOBALS['TSFE']->config['config']['language']);
571
            $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...
572 2
            $registration->setWaitlist($isWaitlistRegistration);
573 2
            $registration->_setProperty('_languageUid', $this->getSysLanguageUid());
574 2
            $this->registrationRepository->add($registration);
575 2
576 2
            // Persist registration, so we have an UID
577 2
            $this->objectManager->get(PersistenceManager::class)->persistAll();
578 2
579 2
            if ($isWaitlistRegistration) {
580 2
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
581 2
            } else {
582 2
                $messageType = MessageType::REGISTRATION_NEW;
583 2
            }
584 2
585 2
            // Fix event in registration for language other than default language
586 2
            $this->registrationService->fixRegistrationEvent($registration, $event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 544 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...
587 2
588 2
            $this->signalDispatch(__CLASS__, __FUNCTION__ . 'AfterRegistrationSaved', [$registration, $this]);
589
590
            // Send notifications to user and admin if confirmation link should be sent
591
            if (!$autoConfirmation) {
592
                $this->notificationService->sendUserMessage(
593
                    $event,
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 544 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...
594
                    $registration,
595
                    $this->settings,
596
                    $messageType
597
                );
598 12
                $this->notificationService->sendAdminMessage(
599
                    $event,
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->checkPidOfEventRecord($event) on line 544 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...
600 12
                    $registration,
601 12
                    $this->settings,
602 12
                    $messageType
603 12
                );
604
            }
605 12
606 10
            // Create given amount of registrations if necessary
607
            $createDependingRegistrations = $registration->getAmountOfRegistrations() > 1;
608 10
            $this->signalDispatch(
609 2
                __CLASS__,
610 2
                __FUNCTION__ . 'BeforeCreateDependingRegistrations',
611
                [$registration, &$createDependingRegistrations, $this]
612 10
            );
613 2
            if ($createDependingRegistrations) {
614 2
                $this->registrationService->createDependingRegistrations($registration);
615 10
            }
616
617 12
            // Flush page cache for event, since new registration has been added
618 2
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
619 2
        }
620
621 12
        if ($autoConfirmation && $success) {
622 12
            $this->redirect(
623
                'confirmRegistration',
624 12
                null,
625
                null,
626 12
                [
627 12
                    'reguid' => $registration->getUid(),
628 12
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid())
629 12
                ]
630 12
            );
631 12
        } else {
632
            $this->redirect(
633
                'saveRegistrationResult',
634
                null,
635
                null,
636
                [
637
                    'result' => $result,
638
                    'eventuid' => $event->getUid(),
639 18
                    'hmac' => $this->hashService->generateHmac('event-' . $event->getUid())
640
                ]
641 18
            );
642
        }
643
    }
644
645
    /**
646
     * Shows the result of the saveRegistrationAction
647
     *
648
     * @param int $result Result
649
     * @param int $eventuid
650
     * @param string $hmac
651
     *
652
     * @return void
653
     */
654
    public function saveRegistrationResultAction($result, $eventuid, $hmac)
655
    {
656
        $event = null;
657
658
        switch ($result) {
659
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
660
                $messageKey = 'event.message.registrationsuccessful';
661
                $titleKey = 'registrationResult.title.successful';
662
                break;
663
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
664
                $messageKey = 'event.message.registrationwaitlistsuccessful';
665
                $titleKey = 'registrationWaitlistResult.title.successful';
666
                break;
667
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
668
                $messageKey = 'event.message.registrationfailedeventexpired';
669
                $titleKey = 'registrationResult.title.failed';
670
                break;
671
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
672
                $messageKey = 'event.message.registrationfailedmaxparticipants';
673
                $titleKey = 'registrationResult.title.failed';
674
                break;
675
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
676
                $messageKey = 'event.message.registrationfailednotenabled';
677
                $titleKey = 'registrationResult.title.failed';
678
                break;
679
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
680
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
681
                $titleKey = 'registrationResult.title.failed';
682
                break;
683
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
684
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
685
                $titleKey = 'registrationResult.title.failed';
686
                break;
687
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
688
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
689
                $titleKey = 'registrationResult.title.failed';
690
                break;
691
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
692
                $messageKey = 'event.message.registrationfailedemailnotunique';
693
                $titleKey = 'registrationResult.title.failed';
694
                break;
695
            default:
696
                $messageKey = '';
697
                $titleKey = '';
698
        }
699
700
        if (!$this->hashService->validateHmac('event-' . $eventuid, $hmac)) {
701
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
702
            $titleKey = 'registrationResult.title.failed';
703
        } else {
704
            $event = $this->eventRepository->findByUid((int)$eventuid);
705
        }
706
707
        $this->view->assignMultiple([
708
            'messageKey' => $messageKey,
709
            'titleKey' => $titleKey,
710
            'event' => $event,
711
        ]);
712
    }
713
714
    /**
715
     * Confirms the registration if possible and sends e-mails to admin and user
716
     *
717
     * @param int $reguid UID of registration
718
     * @param string $hmac HMAC for parameters
719
     *
720
     * @return void
721
     */
722
    public function confirmRegistrationAction($reguid, $hmac)
723
    {
724
        $event = null;
725
726
        /* @var $registration Registration */
727
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkConfirmRegistration(
728
            $reguid,
729
            $hmac
730
        );
731
732
        if ($failed === false) {
733
            $registration->setConfirmed(true);
734
            $event = $registration->getEvent();
735
            $this->registrationRepository->update($registration);
736
737
            $this->signalDispatch(__CLASS__, __FUNCTION__ . 'AfterRegistrationConfirmed', [$registration, $this]);
738
739
            $messageType = MessageType::REGISTRATION_CONFIRMED;
740
            if ($registration->getWaitlist()) {
741
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
742
            }
743
744
            // Send notifications to user and admin
745
            $this->notificationService->sendUserMessage(
746
                $registration->getEvent(),
747
                $registration,
748
                $this->settings,
749
                $messageType
750
            );
751
            $this->notificationService->sendAdminMessage(
752
                $registration->getEvent(),
753
                $registration,
754
                $this->settings,
755
                $messageType
756
            );
757
758
            // Confirm registrations depending on main registration if necessary
759
            if ($registration->getAmountOfRegistrations() > 1) {
760
                $this->registrationService->confirmDependingRegistrations($registration);
761
            }
762
        }
763
764
        // Redirect to payment provider if payment/redirect is enabled
765
        $paymentPid = (int)$this->settings['paymentPid'];
766
        if (!$failed && $paymentPid > 0 && $this->registrationService->redirectPaymentEnabled($registration)) {
767
            $this->uriBuilder->reset()
768
                ->setTargetPageUid($paymentPid)
769
                ->setUseCacheHash(false);
770
            $uri = $this->uriBuilder->uriFor(
771
                'redirect',
772
                [
773
                    'registration' => $registration,
774
                    'hmac' => $this->hashService->generateHmac('redirectAction-' . $registration->getUid())
775
                ],
776
                'Payment',
777
                'sfeventmgt',
778
                'Pipayment'
779
            );
780
            $this->redirectToUri($uri);
781
        }
782
783
        $values = [
784
            'messageKey' => $messageKey,
785
            'titleKey' => $titleKey,
786
            'event' => $event,
787
            'registration' => $registration,
788
        ];
789
790
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
791
        $this->view->assignMultiple($values);
792
    }
793
794
    /**
795
     * Cancels the registration if possible and sends e-mails to admin and user
796
     *
797
     * @param int $reguid UID of registration
798
     * @param string $hmac HMAC for parameters
799
     *
800
     * @return void
801
     */
802
    public function cancelRegistrationAction($reguid, $hmac)
803
    {
804
        $event = null;
805
806
        /* @var $registration Registration */
807
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkCancelRegistration($reguid, $hmac);
808
809
        if ($failed === false) {
810
            $event = $registration->getEvent();
811
812
            // Send notifications (must run before cancelling the registration)
813
            $this->notificationService->sendUserMessage(
814
                $registration->getEvent(),
815
                $registration,
816
                $this->settings,
817
                MessageType::REGISTRATION_CANCELLED
818
            );
819
            $this->notificationService->sendAdminMessage(
820
                $registration->getEvent(),
821
                $registration,
822
                $this->settings,
823
                MessageType::REGISTRATION_CANCELLED
824
            );
825
826
            // First cancel depending registrations
827
            if ($registration->getAmountOfRegistrations() > 1) {
828
                $this->registrationService->cancelDependingRegistrations($registration);
829
            }
830
831
            // Finally cancel registration
832
            $this->registrationRepository->remove($registration);
833
834
            // Dispatch signal, so waitlist registrations can be moved up
835
            $this->signalDispatch(__CLASS__, __FUNCTION__ . 'WaitlistMoveUp', [$event, $this]);
836
837
            // Flush page cache for event, since new registration has been added
838
            $this->eventCacheService->flushEventCache($event->getUid(), $event->getPid());
839
        }
840
841
        $values = [
842
            'messageKey' => $messageKey,
843
            'titleKey' => $titleKey,
844
            'event' => $event,
845
        ];
846
847
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
848
        $this->view->assignMultiple($values);
849
    }
850
851
    /**
852
     * Set date format for field startDate and endDate
853
     *
854
     * @return void
855
     */
856
    public function initializeSearchAction()
857
    {
858
        if ($this->settings !== null && $this->settings['search']['dateFormat']) {
859
            $this->arguments->getArgument('searchDemand')
860
                ->getPropertyMappingConfiguration()->forProperty('startDate')
861
                ->setTypeConverterOption(
862
                    DateTimeConverter::class,
863
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
864
                    $this->settings['search']['dateFormat']
865
                );
866
            $this->arguments->getArgument('searchDemand')
867
                ->getPropertyMappingConfiguration()->forProperty('endDate')
868
                ->setTypeConverterOption(
869
                    DateTimeConverter::class,
870
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
871
                    $this->settings['search']['dateFormat']
872
                );
873
        }
874
        if ($this->arguments->hasArgument('searchDemand')) {
875
            $propertyMappingConfiguration = $this->arguments->getArgument('searchDemand')
876
                ->getPropertyMappingConfiguration();
877
            $propertyMappingConfiguration->allowAllProperties();
878
            $propertyMappingConfiguration->setTypeConverterOption(
879
                PersistentObjectConverter::class,
880
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED,
881
                true
882
            );
883
        }
884
    }
885
886
    /**
887
     * Search view
888
     *
889
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
890
     * @param array $overwriteDemand OverwriteDemand
891
     *
892
     * @return void
893
     */
894
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
895
    {
896
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
897
        $eventDemand->setSearchDemand($searchDemand);
0 ignored issues
show
Bug introduced by
It seems like $searchDemand defined by parameter $searchDemand on line 894 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...
898
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
899
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
900
901
        if ($searchDemand !== null) {
902
            $searchDemand->setFields($this->settings['search']['fields']);
903
904
            if ($this->settings['search']['adjustTime'] && $searchDemand->getStartDate() !== null) {
905
                $searchDemand->getStartDate()->setTime(0, 0, 0);
906
            }
907
908
            if ($this->settings['search']['adjustTime'] && $searchDemand->getEndDate() !== null) {
909
                $searchDemand->getEndDate()->setTime(23, 59, 59);
910
            }
911
        }
912
913
        if ($this->isOverwriteDemand($overwriteDemand)) {
914
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
915
        }
916
917
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
918
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
919
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
920
        $speakers = $this->speakerRepository->findDemanded($foreignRecordDemand);
921
        $events = $this->eventRepository->findDemanded($eventDemand);
922
923
        $values = [
924
            'events' => $events,
925
            'categories' => $categories,
926
            'locations' => $locations,
927
            'organisators' => $organisators,
928
            'speakers' => $speakers,
929
            'searchDemand' => $searchDemand,
930
            'overwriteDemand' => $overwriteDemand,
931
        ];
932
933
        $this->signalDispatch(__CLASS__, __FUNCTION__ . 'BeforeRenderView', [&$values, $this]);
934
        $this->view->assignMultiple($values);
935
    }
936
937
    /**
938
     * Returns if a demand object can be overwritten with the given overwriteDemand array
939
     *
940
     * @param array $overwriteDemand
941
     * @return bool
942
     */
943
    protected function isOverwriteDemand($overwriteDemand)
944
    {
945
        return $this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== [];
946
    }
947
948
    /**
949
     * If no event is given and the singleEvent setting is set, the configured single event is returned
950
     *
951
     * @param Event|null $event
952
     * @return Event|null
953
     */
954
    protected function evaluateSingleEventSetting($event)
955
    {
956
        if ($event === null && (int)$this->settings['singleEvent'] > 0) {
957
            $event = $this->eventRepository->findByUid((int)$this->settings['singleEvent']);
958
        }
959
960
        return $event;
961
    }
962
963
    /**
964
     * If no event is given and the isShortcut setting is set, the event is displayed using the "Insert Record"
965
     * content element and should be loaded from contect object data
966
     *
967
     * @param Event|null $event
968
     * @return Event|null
969
     */
970
    protected function evaluateIsShortcutSetting($event)
971
    {
972
        if ($event === null && (bool)$this->settings['detail']['isShortcut']) {
973
            $eventRawData = $this->configurationManager->getContentObject()->data;
974
            $event = $this->eventRepository->findByUid($eventRawData['uid']);
975
        }
976
977
        return $event;
978
    }
979
980
    /**
981
     * Checks if the event pid could be found in the storagePage settings of the detail plugin and
982
     * if the pid could not be found it return null instead of the event object.
983
     *
984
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
985
     * @return null|\DERHANSEN\SfEventMgt\Domain\Model\Event
986
     */
987
    protected function checkPidOfEventRecord(Event $event)
988
    {
989
        $allowedStoragePages = GeneralUtility::trimExplode(
990
            ',',
991
            Page::extendPidListByChildren(
992
                $this->settings['storagePage'],
993
                $this->settings['recursive']
994
            ),
995
            true
996
        );
997
        if (count($allowedStoragePages) > 0 && !in_array($event->getPid(), $allowedStoragePages)) {
998
            $this->signalSlotDispatcher->dispatch(
999
                __CLASS__,
1000
                'checkPidOfEventRecordFailedInDetailAction',
1001
                [
1002
                    'event' => $event,
1003
                    'eventController' => $this
1004
                ]
1005
            );
1006
            $event = null;
1007
        }
1008
1009
        return $event;
1010
    }
1011
1012
    /**
1013
     * Returns the current sys_language_uid
1014
     *
1015
     * @return int
1016
     */
1017
    protected function getSysLanguageUid()
1018
    {
1019
        return $GLOBALS['TSFE']->sys_language_uid;
1020
    }
1021
}
1022