Completed
Push — master ( 22e1bb...96416a )
by Torben
04:49
created

EventController::saveRegistrationResultAction()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 43
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 9

Importance

Changes 4
Bugs 1 Features 1
Metric Value
c 4
b 1
f 1
dl 0
loc 43
ccs 40
cts 40
cp 1
rs 4.909
cc 9
eloc 39
nc 9
nop 1
crap 9
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\Extbase\Configuration\ConfigurationManagerInterface;
25
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
26
27
/**
28
 * EventController
29
 *
30
 * @author Torben Hansen <[email protected]>
31
 */
32
class EventController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
33
{
34
35
    /**
36
     * Configuration Manager
37
     *
38
     * @var ConfigurationManagerInterface
39
     */
40
    protected $configurationManager;
41
42
    /**
43
     * EventRepository
44
     *
45
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\EventRepository
46
     * @inject
47
     */
48
    protected $eventRepository = null;
49
50
    /**
51
     * Registration repository
52
     *
53
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
54
     * @inject
55
     */
56
    protected $registrationRepository = null;
57
58
    /**
59
     * Category repository
60
     *
61
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\CategoryRepository
62
     * @inject
63
     */
64
    protected $categoryRepository = null;
65
66
    /**
67
     * Location repository
68
     *
69
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\LocationRepository
70
     * @inject
71
     */
72
    protected $locationRepository = null;
73
74
    /**
75
     * Notification Service
76
     *
77
     * @var \DERHANSEN\SfEventMgt\Service\NotificationService
78
     * @inject
79
     */
80
    protected $notificationService = null;
81
82
    /**
83
     * ICalendar Service
84
     *
85
     * @var \DERHANSEN\SfEventMgt\Service\ICalendarService
86
     * @inject
87
     */
88
    protected $icalendarService = null;
89
90
    /**
91
     * Hash Service
92
     *
93
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
94
     * @inject
95
     */
96
    protected $hashService;
97
98
    /**
99
     * RegistrationService
100
     *
101
     * @var \DERHANSEN\SfEventMgt\Service\RegistrationService
102
     * @inject
103
     */
104
    protected $registrationService = null;
105
106
    /**
107
     * UtilityService
108
     *
109
     * @var \DERHANSEN\SfEventMgt\Service\UtilityService
110
     * @inject
111
     */
112
    protected $utilityService = null;
113
114
    /**
115
     * Properties in this array will be ignored by overwriteDemandObject()
116
     *
117
     * @var array
118
     */
119
    protected $ignoredSettingsForOverwriteDemand = ['storagePage'];
120
121
    /**
122
     * Creates an event demand object with the given settings
123
     *
124
     * @param array $settings The settings
125
     *
126
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
127
     */
128 2
    public function createEventDemandObjectFromSettings(array $settings)
129
    {
130
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand */
131 2
        $demand = $this->objectManager->get('DERHANSEN\\SfEventMgt\\Domain\\Model\\Dto\\EventDemand');
132 2
        $demand->setDisplayMode($settings['displayMode']);
133 2
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
134 2
        $demand->setCategory($settings['category']);
135 2
        $demand->setIncludeSubcategories($settings['includeSubcategories']);
136 2
        $demand->setTopEventRestriction((int)$settings['topEventRestriction']);
137 2
        $demand->setOrderField($settings['orderField']);
138 2
        $demand->setOrderDirection($settings['orderDirection']);
139 2
        $demand->setQueryLimit($settings['queryLimit']);
140 2
        $demand->setLocation($settings['location']);
141 2
        return $demand;
142
    }
143
144
    /**
145
     * Creates a foreign record demand object with the given settings
146
     *
147
     * @param array $settings The settings
148
     *
149
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand
150
     */
151
    public function createForeignRecordDemandObjectFromSettings(array $settings)
152
    {
153
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\ForeignRecordDemand $demand */
154
        $demand = $this->objectManager->get('DERHANSEN\\SfEventMgt\\Domain\\Model\\Dto\\ForeignRecordDemand');
155
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
156
        $demand->setRestrictForeignRecordsToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
157
        return $demand;
158
    }
159
160
    /**
161
     * Creates a category demand object with the given settings
162
     *
163
     * @param array $settings The settings
164
     *
165
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand
166
     */
167 2
    public function createCategoryDemandObjectFromSettings(array $settings)
168
    {
169
        /** @var \DERHANSEN\SfEventMgt\Domain\Model\Dto\CategoryDemand $demand */
170 2
        $demand = $this->objectManager->get('DERHANSEN\\SfEventMgt\\Domain\\Model\\Dto\\CategoryDemand');
171 2
        $demand->setStoragePage(Page::extendPidListByChildren($settings['storagePage'], $settings['recursive']));
172 2
        $demand->setRestrictToStoragePage((bool)$settings['restrictForeignRecordsToStoragePage']);
173 2
        $demand->setCategories($settings['categoryMenu']['categories']);
174 2
        $demand->setIncludeSubcategories($settings['categoryMenu']['includeSubcategories']);
175 2
        return $demand;
176
    }
177
178
    /**
179
     * Overwrites a given demand object by an propertyName =>  $propertyValue array
180
     *
181
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand $demand Demand
182
     * @param array $overwriteDemand OwerwriteDemand
183
     *
184
     * @return \DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand
185
     */
186 4
    protected function overwriteEventDemandObject(EventDemand $demand, array $overwriteDemand)
187
    {
188 4
        foreach ($this->ignoredSettingsForOverwriteDemand as $property) {
189 4
            unset($overwriteDemand[$property]);
190 4
        }
191
192 4
        foreach ($overwriteDemand as $propertyName => $propertyValue) {
193 4
            \TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($demand, $propertyName, $propertyValue);
194 4
        }
195 4
        return $demand;
196
    }
197
198
    /**
199
     * List view
200
     *
201
     * @param array $overwriteDemand OverwriteDemand
202
     *
203
     * @return void
204
     */
205 6
    public function listAction(array $overwriteDemand = [])
206
    {
207 6
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
208 6
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
209 6
        $categoryDemand = $this->createCategoryDemandObjectFromSettings($this->settings);
210 6
        if ($this->isOverwriteDemand($overwriteDemand)) {
211 2
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
212 2
        }
213 6
        $events = $this->eventRepository->findDemanded($eventDemand);
214 6
        $categories = $this->categoryRepository->findDemanded($categoryDemand);
215 6
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
216 6
        $this->view->assign('events', $events);
217 6
        $this->view->assign('categories', $categories);
218 6
        $this->view->assign('locations', $locations);
219 6
        $this->view->assign('overwriteDemand', $overwriteDemand);
220 6
    }
221
222
    /**
223
     * Detail view for an event
224
     *
225
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
226
     *
227
     * @return void
228
     */
229 2
    public function detailAction(Event $event = null)
230
    {
231 2
        $this->view->assign('event', $event);
232 2
    }
233
234
    /**
235
     * Initiates the iCalendar download for the given event
236
     *
237
     * @param Event $event The event
238
     *
239
     * @return bool
240
     */
241 2
    public function icalDownloadAction(Event $event)
242
    {
243 2
        $this->icalendarService->downloadiCalendarFile($event);
244 2
        return false;
245
    }
246
247
    /**
248
     * Registration view for an event
249
     *
250
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
251
     *
252
     * @return void
253
     */
254 2
    public function registrationAction(Event $event)
255
    {
256 2
        $this->view->assign('event', $event);
257 2
    }
258
259
    /**
260
     * Set date format for field dateOfBirth
261
     *
262
     * @return void
263
     */
264 2
    public function initializeSaveRegistrationAction()
265
    {
266 2
        $this->arguments->getArgument('registration')
267 2
            ->getPropertyMappingConfiguration()->forProperty('dateOfBirth')
268 2
            ->setTypeConverterOption(
269 2
                'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
270 2
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
271 2
                $this->settings['registration']['formatDateOfBirth']
272 2
            );
273 2
    }
274
275
    /**
276
     * Saves the registration
277
     *
278
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
279
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
280
     * @validate $registration \DERHANSEN\SfEventMgt\Validation\Validator\RegistrationValidator
281
     *
282
     * @return void
283
     */
284 20
    public function saveRegistrationAction(Registration $registration, Event $event)
285
    {
286 20
        $autoConfirmation = (bool)$this->settings['registration']['autoConfirmation'];
287 20
        $result = RegistrationResult::REGISTRATION_SUCCESSFUL;
288 20
        $success = $this->registrationService->checkRegistrationSuccess($event, $registration, $result);
289
290
        // Save registration if no errors
291 20
        if ($success) {
292 6
            $linkValidity = (int)$this->settings['confirmation']['linkValidity'];
293 6
            if ($linkValidity === 0) {
294
                // Use 3600 seconds as default value if not set
295 6
                $linkValidity = 3600;
296 6
            }
297 6
            $confirmationUntil = new \DateTime();
298 6
            $confirmationUntil->add(new \DateInterval('PT' . $linkValidity . 'S'));
299
300 6
            $registration->setEvent($event);
301 6
            $registration->setPid($event->getPid());
302 6
            $registration->setConfirmationUntil($confirmationUntil);
303 6
            $registration->setLanguage($GLOBALS['TSFE']->config['config']['language']);
304 6
            $registration->setFeUser($this->registrationService->getCurrentFeUserObject());
305 6
            $registration->_setProperty('_languageUid', $GLOBALS['TSFE']->sys_language_uid);
306 6
            $this->registrationRepository->add($registration);
307
308
            // Persist registration, so we have an UID
309 6
            $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager')->persistAll();
310
311
            // Add new registration to event
312 6
            $event->addRegistration($registration);
313 6
            $this->eventRepository->update($event);
314
315
            // Send notifications to user and admin if confirmation link should be sent
316 6
            if (!$autoConfirmation) {
317 4
                $this->notificationService->sendUserMessage(
318 4
                    $event,
319 4
                    $registration,
320 4
                    $this->settings,
321
                    MessageType::REGISTRATION_NEW
322 4
                );
323 4
                $this->notificationService->sendAdminMessage(
324 4
                    $event,
325 4
                    $registration,
326 4
                    $this->settings,
327
                    MessageType::REGISTRATION_NEW
328 4
                );
329 4
            }
330
331
            // Create given amount of registrations if necessary
332 6
            if ($registration->getAmountOfRegistrations() > 1) {
333 2
                $this->registrationService->createDependingRegistrations($registration);
334 2
            }
335
336
            // Clear cache for configured pages
337 6
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
338 6
        }
339
340 20
        if ($autoConfirmation && $success) {
341 2
            $this->redirect(
342 2
                'confirmRegistration',
343 2
                null,
344 2
                null,
345
                [
346 2
                    'reguid' => $registration->getUid(),
347 2
                    'hmac' => $this->hashService->generateHmac('reg-' . $registration->getUid())
348 2
                ]
349 2
            );
350 2
        } else {
351 18
            $this->redirect(
352 18
                'saveRegistrationResult',
353 18
                null,
354 18
                null,
355 18
                ['result' => $result]
356 18
            );
357
        }
358 20
    }
359
360
    /**
361
     * Shows the result of the saveRegistrationAction
362
     *
363
     * @param int $result Result
364
     *
365
     * @return void
366
     */
367 18
    public function saveRegistrationResultAction($result)
368
    {
369
        switch ($result) {
370 18
            case RegistrationResult::REGISTRATION_SUCCESSFUL:
371 2
                $messageKey = 'event.message.registrationsuccessful';
372 2
                $titleKey = 'registrationResult.title.successful';
373 2
                break;
374 16
            case RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED:
375 2
                $messageKey = 'event.message.registrationfailedeventexpired';
376 2
                $titleKey = 'registrationResult.title.failed';
377 2
                break;
378 14
            case RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS:
379 2
                $messageKey = 'event.message.registrationfailedmaxparticipants';
380 2
                $titleKey = 'registrationResult.title.failed';
381 2
                break;
382 12
            case RegistrationResult::REGISTRATION_NOT_ENABLED:
383 2
                $messageKey = 'event.message.registrationfailednotenabled';
384 2
                $titleKey = 'registrationResult.title.failed';
385 2
                break;
386 10
            case RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED:
387 2
                $messageKey = 'event.message.registrationfaileddeadlineexpired';
388 2
                $titleKey = 'registrationResult.title.failed';
389 2
                break;
390 8
            case RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES:
391 2
                $messageKey = 'event.message.registrationfailednotenoughfreeplaces';
392 2
                $titleKey = 'registrationResult.title.failed';
393 2
                break;
394 6
            case RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED:
395 2
                $messageKey = 'event.message.registrationfailedmaxamountregistrationsexceeded';
396 2
                $titleKey = 'registrationResult.title.failed';
397 2
                break;
398 4
            case RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE:
399 2
                $messageKey = 'event.message.registrationfailedemailnotunique';
400 2
                $titleKey = 'registrationResult.title.failed';
401 2
                break;
402 2
            default:
403 2
                $messageKey = '';
404 2
                $titleKey = '';
405 2
        }
406
407 18
        $this->view->assign('messageKey', $messageKey);
408 18
        $this->view->assign('titleKey', $titleKey);
409 18
    }
410
411
    /**
412
     * Confirms the registration if possible and sends e-mails to admin and user
413
     *
414
     * @param int $reguid UID of registration
415
     * @param string $hmac HMAC for parameters
416
     *
417
     * @return void
418
     */
419 4
    public function confirmRegistrationAction($reguid, $hmac)
420
    {
421
        /* @var $registration Registration */
422 4
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkConfirmRegistration($reguid, $hmac);
423
424 4
        if ($failed === false) {
425 2
            $registration->setConfirmed(true);
426 2
            $this->registrationRepository->update($registration);
427
428
            // Send notifications to user and admin
429 2
            $this->notificationService->sendUserMessage(
430 2
                $registration->getEvent(),
431 2
                $registration,
432 2
                $this->settings,
433
                MessageType::REGISTRATION_CONFIRMED
434 2
            );
435 2
            $this->notificationService->sendAdminMessage(
436 2
                $registration->getEvent(),
437 2
                $registration,
438 2
                $this->settings,
439
                MessageType::REGISTRATION_CONFIRMED
440 2
            );
441
442
            // Confirm registrations depending on main registration if necessary
443 2
            if ($registration->getAmountOfRegistrations() > 1) {
444 2
                $this->registrationService->confirmDependingRegistrations($registration);
445 2
            }
446 2
        }
447 4
        $this->view->assign('messageKey', $messageKey);
448 4
        $this->view->assign('titleKey', $titleKey);
449 4
    }
450
451
    /**
452
     * Cancels the registration if possible and sends e-mails to admin and user
453
     *
454
     * @param int $reguid UID of registration
455
     * @param string $hmac HMAC for parameters
456
     *
457
     * @return void
458
     */
459 4
    public function cancelRegistrationAction($reguid, $hmac)
460
    {
461
        /* @var $registration Registration */
462 4
        list($failed, $registration, $messageKey, $titleKey) = $this->registrationService->checkCancelRegistration($reguid, $hmac);
463
464 4
        if ($failed === false) {
465
            // Send notifications (must run before cancelling the registration)
466 2
            $this->notificationService->sendUserMessage(
467 2
                $registration->getEvent(),
468 2
                $registration,
469 2
                $this->settings,
470
                MessageType::REGISTRATION_CANCELLED
471 2
            );
472 2
            $this->notificationService->sendAdminMessage(
473 2
                $registration->getEvent(),
474 2
                $registration,
475 2
                $this->settings,
476
                MessageType::REGISTRATION_CANCELLED
477 2
            );
478
479
            // First cancel depending registrations
480 2
            if ($registration->getAmountOfRegistrations() > 1) {
481 2
                $this->registrationService->cancelDependingRegistrations($registration);
482 2
            }
483
484
            // Finally cancel registration
485 2
            $this->registrationRepository->remove($registration);
486
487
            // Clear cache for configured pages
488 2
            $this->utilityService->clearCacheForConfiguredUids($this->settings);
489 2
        }
490 4
        $this->view->assign('messageKey', $messageKey);
491 4
        $this->view->assign('titleKey', $titleKey);
492 4
    }
493
494
    /**
495
     * Set date format for field startDate and endDate
496
     *
497
     * @return void
498
     */
499 2
    public function initializeSearchAction()
500
    {
501 2
        if ($this->settings !== null && $this->settings['search']['dateFormat']) {
502 2
            $this->arguments->getArgument('searchDemand')
503 2
                ->getPropertyMappingConfiguration()->forProperty('startDate')
504 2
                ->setTypeConverterOption(
505 2
                    'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
506 2
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
507 2
                    $this->settings['search']['dateFormat']
508 2
                );
509 2
            $this->arguments->getArgument('searchDemand')
510 2
                ->getPropertyMappingConfiguration()->forProperty('endDate')
511 2
                ->setTypeConverterOption(
512 2
                    'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
513 2
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
514 2
                    $this->settings['search']['dateFormat']
515 2
                );
516 2
        }
517 2
    }
518
519
    /**
520
     * Search view
521
     *
522
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
523
     * @param array $overwriteDemand OverwriteDemand
524
     *
525
     * @return void
526
     */
527 12
    public function searchAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
528
    {
529 12
        $eventDemand = $this->createEventDemandObjectFromSettings($this->settings);
530 12
        $eventDemand->setSearchDemand($searchDemand);
531 12
        $foreignRecordDemand = $this->createForeignRecordDemandObjectFromSettings($this->settings);
532
533 12
        if ($searchDemand !== null) {
534 10
            $searchDemand->setFields($this->settings['search']['fields']);
535
536 10
            if ($this->settings['search']['adjustTime'] && $searchDemand->getStartDate() !== null) {
537 2
                $searchDemand->getStartDate()->setTime(0, 0, 0);
538 2
            }
539
540 10
            if ($this->settings['search']['adjustTime'] && $searchDemand->getEndDate() !== null) {
541 2
                $searchDemand->getEndDate()->setTime(23, 59, 59);
542 2
            }
543 10
        }
544
545 12
        if ($this->isOverwriteDemand($overwriteDemand)) {
546 2
            $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
547 2
        }
548
549 12
        $categories = $this->categoryRepository->findDemanded($foreignRecordDemand);
550 12
        $locations = $this->locationRepository->findDemanded($foreignRecordDemand);
551
552 12
        $events = $this->eventRepository->findDemanded($eventDemand);
553
554 12
        $this->view->assign('events', $events);
555 12
        $this->view->assign('categories', $categories);
556 12
        $this->view->assign('locations', $locations);
557 12
        $this->view->assign('searchDemand', $searchDemand);
558 12
        $this->view->assign('overwriteDemand', $overwriteDemand);
559 12
    }
560
561
    /**
562
     * Returns if a demand object can be overwritten with the given overwriteDemand array
563
     *
564
     * @param array $overwriteDemand
565
     * @return bool
566
     */
567 18
    protected function isOverwriteDemand($overwriteDemand)
568
    {
569 18
        return $this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== [];
570
    }
571
572
}
573