Completed
Push — payment ( a2694a )
by Torben
42:06
created

EventController::saveRegistrationResultAction()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 43
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

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