Completed
Push — development ( b2c13c...294738 )
by Torben
09:28
created

createEventDemandObjectFromSettings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 5
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 15
nc 1
nop 1
crap 2
1
<?php
2
namespace DERHANSEN\SfEventMgt\Controller;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
18
use DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand;
19
use DERHANSEN\SfEventMgt\Domain\Model\Event;
20
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
21
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
22
use DERHANSEN\SfEventMgt\Utility\MessageType;
23
use DERHANSEN\SfEventMgt\Utility\Page;
24
use TYPO3\CMS\Core\Utility\GeneralUtility;
25
use TYPO3\CMS\Core\Utility\HttpUtility;
26
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
27
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
28
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
29
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
30
use TYPO3\CMS\Fluid\View\StandaloneView;
31
32
/**
33
 * EventController
34
 *
35
 * @author Torben Hansen <[email protected]>
36
 */
37
class EventController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
38
{
39
40
    /**
41
     * Configuration Manager
42
     *
43
     * @var ConfigurationManagerInterface
44
     */
45
    protected $configurationManager;
46
47
    /**
48
     * EventRepository
49
     *
50
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\EventRepository
51
     * @inject
52
     */
53
    protected $eventRepository = null;
54
55
    /**
56
     * Registration repository
57
     *
58
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
59
     * @inject
60
     */
61
    protected $registrationRepository = null;
62
63
    /**
64
     * Category repository
65
     *
66
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\CategoryRepository
67
     * @inject
68
     */
69
    protected $categoryRepository = null;
70
71
    /**
72
     * Location repository
73
     *
74
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\LocationRepository
75
     * @inject
76
     */
77
    protected $locationRepository = null;
78
79
    /**
80
     * Organisator repository
81
     *
82
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\OrganisatorRepository
83
     * @inject
84
     */
85
    protected $organisatorRepository = null;
86
87
    /**
88
     * Notification Service
89
     *
90
     * @var \DERHANSEN\SfEventMgt\Service\NotificationService
91
     * @inject
92
     */
93
    protected $notificationService = null;
94
95
    /**
96
     * ICalendar Service
97
     *
98
     * @var \DERHANSEN\SfEventMgt\Service\ICalendarService
99
     * @inject
100
     */
101
    protected $icalendarService = null;
102
103
    /**
104
     * Hash Service
105
     *
106
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
107
     * @inject
108
     */
109
    protected $hashService;
110
111
    /**
112
     * RegistrationService
113
     *
114
     * @var \DERHANSEN\SfEventMgt\Service\RegistrationService
115
     * @inject
116
     */
117
    protected $registrationService = null;
118
119
    /**
120
     * CalendarService
121
     *
122
     * @var \DERHANSEN\SfEventMgt\Service\CalendarService
123
     * @inject
124
     */
125
    protected $calendarService = null;
126
127
    /**
128
     * UtilityService
129
     *
130
     * @var \DERHANSEN\SfEventMgt\Service\UtilityService
131
     * @inject
132
     */
133
    protected $utilityService = null;
134
135
    /**
136
     * PaymentMethodService
137 1
     *
138
     * @var \DERHANSEN\SfEventMgt\Service\PaymentService
139
     * @inject
140 1
     */
141 1
    protected $paymentService = null;
142 1
    
143 1
    /**
144 1
     * Properties in this array will be ignored by overwriteDemandObject()
145 1
     *
146 1
     * @var array
147 1
     */
148 1
    protected $ignoredSettingsForOverwriteDemand = ['storagepage', 'orderfieldallowed'];
149 1
150 1
    /**
151
     * Creates an event demand object with the given settings
152
     *
153
     * @param array $settings The settings
154
     *
155
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
156
     */
157
    public function createEventDemandObjectFromSettings(array $settings)
158
    {
159
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand */
160
        $demand = $this->objectManager->get('DERHANSEN\\SfEventMgt\\Domain\\Model\\Dto\\EventDemand');
161
        $demand->setDisplayMode($settings['displayMode']);
162
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
163
        $demand->setCategoryConjunction($settings['categoryConjunction']);
164
        $demand->setCategory($settings['category']);
165
        $demand->setIncludeSubcategories($settings['includeSubcategories']);
166
        $demand->setTopEventRestriction((int)$settings['topEventRestriction']);
167
        $demand->setOrderField($settings['orderField']);
168
        $demand->setOrderFieldAllowed($settings['orderFieldAllowed']);
169
        $demand->setOrderDirection($settings['orderDirection']);
170
        $demand->setQueryLimit($settings['queryLimit']);
171
        $demand->setLocation($settings['location']);
172
        $demand->setOrganisator($settings['organisator']);
173
        return $demand;
174
    }
175
176 1
    /**
177
     * Creates a foreign record demand object with the given settings
178
     *
179 1
     * @param array $settings The settings
180 1
     *
181 1
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand
182 1
     */
183 1
    public function createForeignRecordDemandObjectFromSettings(array $settings)
184 1
    {
185
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand $demand */
186
        $demand = $this->objectManager->get('DERHANSEN\\SfEventMgt\\Domain\\Model\\Dto\\ForeignRecordDemand');
187
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
188
        $demand->setRestrictForeignRecordsToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
189
        return $demand;
190
    }
191
192
    /**
193
     * Creates a category demand object with the given settings
194
     *
195 2
     * @param array $settings The settings
196
     *
197 2
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand
198 2
     */
199 2
    public function createCategoryDemandObjectFromSettings(array $settings)
200
    {
201 2
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand $demand */
202 2
        $demand = $this->objectManager->get('DERHANSEN\\SfEventMgt\\Domain\\Model\\Dto\\CategoryDemand');
203 2
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
204 2
        $demand->setRestrictToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
205
        $demand->setCategories($settings['categoryMenu']['categories']);
206
        $demand->setIncludeSubcategories($settings['categoryMenu']['includeSubcategories']);
207
        return $demand;
208
    }
209
210
    /**
211
     * Overwrites a given demand object by an propertyName =>  $propertyValue array
212
     *
213
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand Demand
214
     * @param array $overwriteDemand OwerwriteDemand
215
     *
216
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
217
     */
218
    protected function overwriteEventDemandObject(EventDemand $demand, array $overwriteDemand)
219
    {
220
        foreach ($this->ignoredSettingsForOverwriteDemand as $property) {
221
            unset($overwriteDemand[$property]);
222
        }
223
224
        foreach ($overwriteDemand as $propertyName => $propertyValue) {
225
            if (in_array(strtolower($propertyName), $this->ignoredSettingsForOverwriteDemand, true)) {
226 3
                continue;
227
            }
228 3
            \TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($demand, $propertyName, $propertyValue);
229 3
        }
230 3
        return $demand;
231 3
    }
232 1
233 1
    /**
234 3
     * Hook into request processing and catch exceptions
235 3
     *
236 3
     * @param RequestInterface $request
237 3
     * @param ResponseInterface $response
238 3
     * @throws \Exception
239 3
     */
240 3
    public function processRequest(RequestInterface $request, ResponseInterface $response)
241 3
    {
242
        try {
243
            parent::processRequest($request, $response);
244
        } catch (\Exception $exception) {
245
            $this->handleKnownExceptionsElseThrowAgain($exception);
246
        }
247
    }
248
249
    /**
250 1
     * Handle known exceptions
251
     *
252 1
     * @param \Exception $exception
253 1
     * @throws \Exception
254
     */
255
    private function handleKnownExceptionsElseThrowAgain(\Exception $exception)
256
    {
257
        $previousException = $exception->getPrevious();
258
        if (($this->actionMethodName === 'detailAction' || $this->actionMethodName === 'registrationAction')
259
            && $previousException instanceof \TYPO3\CMS\Extbase\Property\Exception
260
        ) {
261
            $this->handleEventNotFoundError($this->settings);
262 1
        } else {
263
            throw $exception;
264 1
        }
265 1
    }
266
267
    /**
268
     * Initialize list action and set format
269
     *
270
     * @return void
271
     */
272
    public function initializeListAction()
273
    {
274
        if (isset($this->settings['list']['format'])) {
275 1
            $this->request->setFormat($this->settings['list']['format']);
276
        }
277 1
    }
278
279
    /**
280 1
     * List view
281
     *
282 1
     * @param array $overwriteDemand OverwriteDemand
283 1
     *
284 1
     * @return void
285
     */
286
    public function listAction(array $overwriteDemand = [])
287
    {
288
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
289
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
290
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
291 1
        if ($this->isOverwriteDemand($overwriteDemand)) {
292
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
293 1
        }
294 1
        $events = $this->eventRepository->findDemanded($eventDemand);
295 1
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
296 1
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
297 1
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
298 1
        $this->view->assignMultiple([
299 1
            'events' => $events,
300 1
            'categories' => $categories,
301
            'locations' => $locations,
302
            'organisators' => $organisators,
303
            'overwriteDemand' => $overwriteDemand,
304
            'eventDemand' => $eventDemand
305
        ]);
306
    }
307
308
    /**
309
     * Calendar view
310
     *
311 11
     * @param array $overwriteDemand OverwriteDemand
312
     *
313 11
     * @return void
314 11
     */
315 11
    public function calendarAction(array $overwriteDemand = [])
316
    {
317
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
318 11
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
319 4
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
320 4
        if ($this->isOverwriteDemand($overwriteDemand)) {
321 4
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
322 4
        }
323 4
324 4
        // Set month/year to demand if not given
325
        if (!$eventDemand->getMonth()) {
326 4
            $currentMonth = date('n');
327 4
            $eventDemand->setMonth($currentMonth);
328 4
        } else {
329 4
            $currentMonth = $eventDemand->getMonth();
330
        }
331 4
        if (!$eventDemand->getYear()) {
332 4
            $currentYear = date('Y');
333 4
            $eventDemand->setYear($currentYear);
334 4
        } else {
335 4
            $currentYear = $eventDemand->getYear();
336 4
        }
337 4
338 4
        // Set demand from calendar date range instead of month / year
339
        if ((bool)$this->settings['calendar']['includeEventsForEveryDayOfAllCalendarWeeks']) {
340
            $eventDemand = $this->changeEventDemandToFullMonthDateRange($eventDemand);
341 4
        }
342
343
        $events = $this->eventRepository->findDemanded($eventDemand);
344 4
        $weeks = $this->calendarService->getCalendarArray(
345 1
            $currentMonth,
346 1
            $currentYear,
347 1
            strtotime('today midnight'),
348 3
            (int)$this->settings['calendar']['firstDayOfWeek'],
349 3
            $events
350
        );
351 4
352
        $values = [
353
            'weeks' => $weeks,
354 4
            'categories' => $this->categoryRepository->findDemanded($categoryDemand),
355 3
            'locations' => $this->locationRepository->findDemanded($foreignRecordDemand),
356 3
            'organisators' => $this->organisatorRepository->findDemanded($foreignRecordDemand),
357 3
            'eventDemand' => $eventDemand,
358 3
            'overwriteDemand' => $overwriteDemand,
359
            'currentPageId' => $GLOBALS['TSFE']->id,
360 3
            'firstDayOfMonth' => \DateTime::createFromFormat('d.m.Y', sprintf('1.%s.%s', $currentMonth, $currentMonth)),
361 3
            'previousMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '-1 month'),
362 3
            'nextMonthConfig' => $this->calendarService->getDateConfig($currentMonth, $currentYear, '+1 month')
363 3
        ];
364 3
365
        $this->view->assignMultiple($values);
366 3
    }
367 3
368
    /**
369
     * Changes the given event demand object to select a date range for a calendar month including days of the previous
370 4
     * month for the first week and they days for the next month for the last week
371 1
     *
372 1
     * @param EventDemand $eventDemand
373
     * @return EventDemand
374
     */
375 4
    protected function changeEventDemandToFullMonthDateRange(EventDemand $eventDemand)
376 4
    {
377
        $calendarDateRange = $this->calendarService->getCalendarDateRange(
378 11
            $eventDemand->getMonth(),
379 1
            $eventDemand->getYear(),
380 1
            $this->settings['calendar']['firstDayOfWeek']
381 1
        );
382 1
383
        $eventDemand->setMonth(0);
384 1
        $eventDemand->setYear(0);
385 1
386 1
        $startDate = new \DateTime();
387 1
        $startDate->setTimestamp($calendarDateRange['firstDayOfCalendar']);
388 1
        $endDate = new \DateTime();
389 10
        $endDate->setTimestamp($calendarDateRange['lastDayOfCalendar']);
390 10
        $endDate->setTime(23, 59, 59);
391 10
392 10
        $searchDemand = new SearchDemand();
393 10
        $searchDemand->setStartDate($startDate);
394 10
        $searchDemand->setEndDate($endDate);
395
        $eventDemand->setSearchDemand($searchDemand);
396 11
        return $eventDemand;
397
    }
398
399
    /**
400
     * Detail view for an event
401
     *
402
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
403
     * @return string
404
     */
405 9
    public function detailAction(Event $event = null)
406
    {
407
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
408 9
            return $this->handleEventNotFoundError($this->settings);
409 1
        }
410 1
        $this->view->assign('event', $event);
411 1
    }
412 8
413
    /**
414
     * Error handling if event is not found
415
     *
416 8
     * @param array $settings
417 1
     * @return string
418 1
     */
419 1
    protected function handleEventNotFoundError($settings)
420 7
    {
421 1
        if (empty($settings['event']['errorHandling'])) {
422 1
            return null;
423 1
        }
424 6
425 1
        $configuration = GeneralUtility::trimExplode(',', $settings['event']['errorHandling'], true);
426 1
427 1
        switch ($configuration[0]) {
428 5
            case 'redirectToListView':
429 1
                $listPid = (int)$settings['listPid'] > 0 ? (int)$settings['listPid'] : 1;
430 1
                $this->redirect('list', null, null, null, $listPid);
431 1
                break;
432 4
            case 'pageNotFoundHandler':
433 1
                $GLOBALS['TSFE']->pageNotFoundAndExit('Event not found.');
434 1
                break;
435 1
            case 'showStandaloneTemplate':
436 3
                if (isset($configuration[2])) {
437 1
                    $statusCode = constant(HttpUtility::class . '::HTTP_STATUS_' . $configuration[2]);
438 1
                    HttpUtility::setResponseCode($statusCode);
439 1
                }
440 2
                $standaloneTemplate = $this->objectManager->get(StandaloneView::class);
441 1
                $standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($configuration[1]));
442 1
                return $standaloneTemplate->render();
443 1
                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...
444 1
            default:
445 1
        }
446 1
    }
447 1
448
    /**
449 9
     * Initiates the iCalendar download for the given event
450 9
     *
451 9
     * @param Event $event The event
452
     *
453
     * @return bool
454
     */
455
    public function icalDownloadAction(Event $event)
456
    {
457
        $this->icalendarService->downloadiCalendarFile($event);
458
        return false;
459
    }
460
461 3
    /**
462
     * Registration view for an event
463
     *
464 3
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
465
     *
466 3
     * @return string
467 2
     */
468 2
    public function registrationAction(Event $event = null)
469
    {
470 2
        if (is_null($event) && isset($this->settings['event']['errorHandling'])) {
471 2
            return $this->handleEventNotFoundError($this->settings);
472 1
        }
473 1
        if ($event->getRestrictPaymentMethods()) {
0 ignored issues
show
Bug introduced by
It seems like $event is not always an object, but can also be of type null. Maybe add an additional type check?

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

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

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

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

function notNullable(stdClass $x) { }

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

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

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
475
        } else {
476 2
            $paymentMethods = $this->paymentService->getPaymentMethods();
477 2
        }
478 2
479 2
        $this->view->assignMultiple([
480
            'event' => $event,
481 2
            'paymentMethods' => $paymentMethods,
482 2
        ]);
483 2
    }
484 2
485 2
    /**
486
     * Set date format for field dateOfBirth
487 2
     *
488
     * @return void
489
     */
490 2
    public function initializeSaveRegistrationAction()
491 2
    {
492 2
        $this->arguments->getArgument('registration')
493 2
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
494
            ->setTypeConverterOption(
495
                'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
496 3
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
497 3
                $this->settings['registration']['formatDateOfBirth']
498
            );
499
    }
500
501
    /**
502
     * Saves the registration
503
     *
504
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
505
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
506
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator
507
     *
508
     * @return void
509
     */
510
    public function saveRegistrationAction(Registration $registration, Event $event)
511
    {
512
        $autoConfirmation = (bool)$this->settings['registration']['autoConfirmation'] || $event->getEnableAutoconfirm();
513
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
514 3
        $success = $this->registrationService->checkRegistrationSuccess($event, $registration, $result);
515 3
516 3
        // Save registration if no errors
517
        if ($success) {
518
            $isWaitlistRegistration = $this->registrationService->isWaitlistRegistration(
519
                $event,
520
                $registration->getAmountOfRegistrations()
521
            );
522
            $linkValidity = (int)$this->settings['confirmation']['linkValidity'];
523
            if ($linkValidity === 0) {
524
                // Use 3600 seconds as default value if not set
525
                $linkValidity = 3600;
526 2
            }
527
            $confirmationUntil = new \DateTime();
528
            $confirmationUntil->add(new \DateInterval('PT' . $linkValidity . 'S'));
529 2
530
            $registration->setEvent($event);
531 2
            $registration->setPid($event->getPid());
532
            $registration->setConfirmationUntil($confirmationUntil);
533 1
            $registration->setLanguage($GLOBALS['TSFE']->config['config']['language']);
534 1
            $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...
535 1
            $registration->setWaitlist($isWaitlistRegistration);
536 1
            $registration->_setProperty('_languageUid', $GLOBALS['TSFE']->sys_language_uid);
537
            $this->registrationRepository->add($registration);
538 1
539 1
            // Persist registration, so we have an UID
540 1
            $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager')->persistAll();
541 1
542 1
            // Add new registration (or waitlist registration) to event
543
            if ($isWaitlistRegistration) {
544 1
                $event->addRegistrationWaitlist($registration);
545
                $messageType = MessageType::REGISTRATION_WAITLIST_NEW;
546
            } else {
547 1
                $event->addRegistration($registration);
548 1
                $messageType = MessageType::REGISTRATION_NEW;
549 1
            }
550
            $this->eventRepository->update($event);
551
552 1
            // Send notifications to user and admin if confirmation link should be sent
553
            if (!$autoConfirmation) {
554
                $this->notificationService->sendUserMessage(
555 1
                    $event,
556 1
                    $registration,
557 2
                    $this->settings,
558 2
                    $messageType
559 2
                );
560
                $this->notificationService->sendAdminMessage(
561
                    $event,
562
                    $registration,
563
                    $this->settings,
564
                    $messageType
565
                );
566 1
            }
567
568 1
            // Create given amount of registrations if necessary
569 1
            if ($registration->getAmountOfRegistrations() > 1) {
570 1
                $this->registrationService->createDependingRegistrations($registration);
571 1
            }
572 1
573 1
            // Clear cache for configured pages
574 1
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
575 1
        }
576 1
577 1
        if ($autoConfirmation && $success) {
578 1
            $this->redirect(
579 1
                'confirmRegistration',
580 1
                null,
581 1
                null,
582 1
                [
583 1
                    'reguid' => $registration->getUid(),
584 1
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid())
585
                ]
586
            );
587
        } else {
588
            $this->redirect(
589
                'saveRegistrationResult',
590
                null,
591
                null,
592
                [
593
                    'result' => $result,
594 6
                    'eventuid' => $event->getUid(),
595
                    'hmac' => $this->hashService->generateHmac('event-' . $event->getUid())
596 6
                ]
597 6
            );
598 6
        }
599 6
    }
600
601 6
    /**
602 5
     * Shows the result of the saveRegistrationAction
603
     *
604 5
     * @param int $result Result
605 1
     * @param int $eventuid
606 1
     * @param string $hmac
607
     *
608 5
     * @return void
609 1
     */
610 1
    public function saveRegistrationResultAction($result, $eventuid, $hmac)
611 5
    {
612
        $event = null;
613 6
614 1
        switch ($result) {
615 1
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
616
                $messageKey = 'event.message.registrationsuccessful';
617 6
                $titleKey = 'registrationResult.title.successful';
618 6
                break;
619
            case RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST:
620 6
                $messageKey = 'event.message.registrationwaitlistsuccessful';
621
                $titleKey = 'registrationWaitlistResult.title.successful';
622 6
                break;
623 6
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
624 6
                $messageKey = 'event.message.registrationfailedeventexpired';
625 6
                $titleKey = 'registrationResult.title.failed';
626 6
                break;
627 6
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
628
                $messageKey = 'event.message.registrationfailedmaxparticipants';
629
                $titleKey = 'registrationResult.title.failed';
630
                break;
631
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
632
                $messageKey = 'event.message.registrationfailednotenabled';
633
                $titleKey = 'registrationResult.title.failed';
634
                break;
635 9
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
636
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
637 9
                $titleKey = 'registrationResult.title.failed';
638
                break;
639
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
640
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
641
                $titleKey = 'registrationResult.title.failed';
642
                break;
643
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
644
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
645
                $titleKey = 'registrationResult.title.failed';
646
                break;
647
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
648
                $messageKey = 'event.message.registrationfailedemailnotunique';
649
                $titleKey = 'registrationResult.title.failed';
650
                break;
651
            default:
652
                $messageKey = '';
653
                $titleKey = '';
654
        }
655
656
        if (!$this->hashService->validateHmac('event-' . $eventuid, $hmac)) {
657
            $messageKey = 'event.message.registrationsuccessfulwrongeventhmac';
658
            $titleKey = 'registrationResult.title.failed';
659
        } else {
660
            $event = $this->eventRepository->findByUid((int)$eventuid);
661
        }
662
663
        $this->view->assignMultiple([
664
            'messageKey' => $messageKey,
665
            'titleKey' => $titleKey,
666
            'event' => $event,
667
        ]);
668
    }
669
670
    /**
671
     * Confirms the registration if possible and sends e-mails to admin and user
672
     *
673
     * @param int $reguid UID of registration
674
     * @param string $hmac HMAC for parameters
675
     *
676
     * @return void
677
     */
678
    public function confirmRegistrationAction($reguid, $hmac)
679
    {
680
        $event = null;
681
682
        /* @var $registration Registration */
683
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkConfirmRegistration(
684
            $reguid,
685
            $hmac
686
        );
687
688
        if ($failed === false) {
689
            $registration->setConfirmed(true);
690
            $event = $registration->getEvent();
691
            $this->registrationRepository->update($registration);
692
693
            $messageType = MessageType::REGISTRATION_CONFIRMED;
694
            if ($registration->getWaitlist()) {
695
                $messageType = MessageType::REGISTRATION_WAITLIST_CONFIRMED;
696
            }
697
698
            // Send notifications to user and admin
699
            $this->notificationService->sendUserMessage(
700
                $registration->getEvent(),
701
                $registration,
702
                $this->settings,
703
                $messageType
704
            );
705
            $this->notificationService->sendAdminMessage(
706
                $registration->getEvent(),
707
                $registration,
708
                $this->settings,
709
                $messageType
710
            );
711
712
            // Confirm registrations depending on main registration if necessary
713
            if ($registration->getAmountOfRegistrations() > 1) {
714
                $this->registrationService->confirmDependingRegistrations($registration);
715
            }
716
        }
717
718
        // Redirect to payment provider if payment/redirect is enabled
719
        $paymentPid = (int)$this->settings['paymentPid'];
720
        if (!$failed && $paymentPid > 0 && $this->registrationService->redirectPaymentEnabled($registration)) {
721
            $this->uriBuilder->reset()
722
                ->setTargetPageUid($paymentPid)
723
                ->setUseCacheHash(false);
724
            $uri =  $this->uriBuilder->uriFor(
725
                'redirect',
726
                [
727
                    'registration' => $registration,
728
                    'hmac' => $this->hashService->generateHmac('redirectAction-' . $registration->getUid())
729
                ],
730
                'Payment',
731
                'sfeventmgt',
732
                'Pipayment'
733
            );
734
            $this->redirectToUri($uri);
735
        }
736
737
        $this->view->assignMultiple([
738
            'messageKey' => $messageKey,
739
            'titleKey' => $titleKey,
740
            'event' => $event,
741
        ]);
742
    }
743
744
    /**
745
     * Cancels the registration if possible and sends e-mails to admin and user
746
     *
747
     * @param int $reguid UID of registration
748
     * @param string $hmac HMAC for parameters
749
     *
750
     * @return void
751
     */
752
    public function cancelRegistrationAction($reguid, $hmac)
753
    {
754
        $event = null;
755
756
        /* @var $registration Registration */
757
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkCancelRegistration($reguid, $hmac);
758
759
        if ($failed === false) {
760
            $event = $registration->getEvent();
761
762
            // Send notifications (must run before cancelling the registration)
763
            $this->notificationService->sendUserMessage(
764
                $registration->getEvent(),
765
                $registration,
766
                $this->settings,
767
                MessageType::REGISTRATION_CANCELLED
768
            );
769
            $this->notificationService->sendAdminMessage(
770
                $registration->getEvent(),
771
                $registration,
772
                $this->settings,
773
                MessageType::REGISTRATION_CANCELLED
774
            );
775
776
            // First cancel depending registrations
777
            if ($registration->getAmountOfRegistrations() > 1) {
778
                $this->registrationService->cancelDependingRegistrations($registration);
779
            }
780
781
            // Finally cancel registration
782
            $this->registrationRepository->remove($registration);
783
784
            // Clear cache for configured pages
785
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
786
        }
787
788
        $this->view->assignMultiple([
789
            'messageKey' => $messageKey,
790
            'titleKey' => $titleKey,
791
            'event' => $event,
792
        ]);
793
    }
794
795
    /**
796
     * Set date format for field startDate and endDate
797
     *
798
     * @return void
799
     */
800
    public function initializeSearchAction()
801
    {
802
        if ($this->settings !== null && $this->settings['search']['dateFormat']) {
803
            $this->arguments->getArgument('searchDemand')
804
                ->getPropertyMappingConfiguration()->forProperty('startDate')
805
                ->setTypeConverterOption(
806
                    'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
807
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
808
                    $this->settings['search']['dateFormat']
809
                );
810
            $this->arguments->getArgument('searchDemand')
811
                ->getPropertyMappingConfiguration()->forProperty('endDate')
812
                ->setTypeConverterOption(
813
                    'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
814
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
815
                    $this->settings['search']['dateFormat']
816
                );
817
        }
818
    }
819
820
    /**
821
     * Search view
822
     *
823
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
824
     * @param array $overwriteDemand OverwriteDemand
825
     *
826
     * @return void
827
     */
828
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
829
    {
830
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
831
        $eventDemand->setSearchDemand($searchDemand);
0 ignored issues
show
Bug introduced by
It seems like $searchDemand defined by parameter $searchDemand on line 828 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...
832
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
833
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
834
835
        if ($searchDemand !== null) {
836
            $searchDemand->setFields($this->settings['search']['fields']);
837
838
            if ($this->settings['search']['adjustTime'] && $searchDemand->getStartDate() !== null) {
839
                $searchDemand->getStartDate()->setTime(0, 0, 0);
840
            }
841
842
            if ($this->settings['search']['adjustTime'] && $searchDemand->getEndDate() !== null) {
843
                $searchDemand->getEndDate()->setTime(23, 59, 59);
844
            }
845
        }
846
847
        if ($this->isOverwriteDemand($overwriteDemand)) {
848
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
849
        }
850
851
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
852
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
853
        $organisators = $this->organisatorRepository->findDemanded($foreignRecordDemand);
854
855
        $events = $this->eventRepository->findDemanded($eventDemand);
856
857
        $this->view->assignMultiple([
858
            'events' => $events,
859
            'categories' => $categories,
860
            'locations' => $locations,
861
            'organisators' => $organisators,
862
            'searchDemand' => $searchDemand,
863
            'overwriteDemand' => $overwriteDemand,
864
        ]);
865
    }
866
867
    /**
868
     * Returns if a demand object can be overwritten with the given overwriteDemand array
869
     *
870
     * @param array $overwriteDemand
871
     * @return bool
872
     */
873
    protected function isOverwriteDemand($overwriteDemand)
874
    {
875
        return $this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== [];
876
    }
877
878
}
879