Completed
Push — development ( deb2fc...28a639 )
by Torben
04:28 queued 25s
created

EventController::injectHashService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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