Completed
Push — development ( 756641...a99d9c )
by Torben
05:28
created

createDependingRegistrations()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
ccs 13
cts 13
cp 1
rs 9.4285
cc 3
eloc 11
nc 3
nop 1
crap 3
1
<?php
2
namespace DERHANSEN\SfEventMgt\Service;
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\Payment\AbstractPayment;
18
use \TYPO3\CMS\Extbase\Reflection\ObjectAccess;
19
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
20
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
21
22
/**
23
 * RegistrationService
24
 *
25
 * @author Torben Hansen <[email protected]>
26
 */
27
class RegistrationService
28
{
29
    /**
30
     * The object manager
31
     *
32
     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
33
     * */
34
    protected $objectManager;
35
36
    /**
37
     * RegistrationRepository
38
     *
39
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
40
     * */
41
    protected $registrationRepository;
42
43
    /**
44
     * FrontendUserRepository
45
     *
46
     * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
47
     * */
48
    protected $frontendUserRepository;
49
50
    /**
51
     * Hash Service
52
     *
53
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
54
     * */
55
    protected $hashService;
56
57
    /**
58
     * Payment Service
59
     *
60
     * @var \DERHANSEN\SfEventMgt\Service\PaymentService
61
     * */
62
    protected $paymentService;
63
64
    /**
65
     * DI for $frontendUserRepository
66
     *
67
     * @param \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
68
     */
69
    public function injectFrontendUserRepository(
70
        \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
71
    ) {
72
        $this->frontendUserRepository = $frontendUserRepository;
73
    }
74
75
    /**
76
     * DI for $hashService
77
     *
78 2
     * @param \TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService
79
     */
80 2
    public function injectHashService(\TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService)
81 2
    {
82 2
        $this->hashService = $hashService;
83
    }
84 2
85 1
    /**
86 1
     * DI for $objectManager
87 1
     *
88 1
     * @param \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
89
     */
90 2
    public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager)
91 2
    {
92 2
        $this->objectManager = $objectManager;
93
    }
94
95
    /**
96
     * DI for $paymentService
97
     *
98
     * @param \DERHANSEN\SfEventMgt\Service\PaymentService $paymentService
99
     */
100
    public function injectPaymentService(\DERHANSEN\SfEventMgt\Service\PaymentService $paymentService)
101
    {
102 1
        $this->paymentService = $paymentService;
103
    }
104 1
105 1
    /**
106
     * DI for $registrationRepository
107 1
     *
108 1
     * @param \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
109 1
     */
110 1
    public function injectRegistrationRepository(
111 1
        \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
112 1
    ) {
113 1
        $this->registrationRepository = $registrationRepository;
114 1
    }
115 1
116 1
    /**
117 1
     * Handles expired registrations. If the $delete parameter is set, then
118
     * registrations are deleted, else just hidden
119
     *
120
     * @param bool $delete Delete
121
     *
122
     * @return void
123
     */
124
    public function handleExpiredRegistrations($delete = false)
125
    {
126 1
        $registrations = $this->registrationRepository->findExpiredRegistrations(new \DateTime());
127
        if ($registrations->count() > 0) {
128 1
            foreach ($registrations as $registration) {
129 1
                /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration */
130
                if ($delete) {
131 1
                    $this->registrationRepository->remove($registration);
132 1
                } else {
133 1
                    $registration->setHidden(true);
134 1
                    $this->registrationRepository->update($registration);
135
                }
136
            }
137
        }
138
    }
139
140
    /**
141
     * Duplicates (all public accessable properties) the given registration the
142
     * amount of times configured in amountOfRegistrations
143
     *
144 4
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
145
     *
146
     * @return void
147 4
     */
148 4
    public function createDependingRegistrations($registration)
149 4
    {
150 4
        $registrations = $registration->getAmountOfRegistrations();
151
        for ($i = 1; $i <= $registrations - 1; $i++) {
152 4
            /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $newReg */
153 1
            $newReg = $this->objectManager->get(Registration::class);
154 1
            $properties = ObjectAccess::getGettableProperties($registration);
155 1
            foreach ($properties as $propertyName => $propertyValue) {
156 1
                ObjectAccess::setProperty($newReg, $propertyName, $propertyValue);
157 3
            }
158
            $newReg->setMainRegistration($registration);
159
            $newReg->setAmountOfRegistrations(1);
160 4
            $newReg->setIgnoreNotifications(true);
161 1
            $this->registrationRepository->add($newReg);
162 1
        }
163 1
    }
164 1
165
    /**
166 4
     * Confirms all depending registrations based on the given main registration
167 1
     *
168 1
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
169 1
     *
170 1
     * @return void
171
     */
172 4
    public function confirmDependingRegistrations($registration)
173 1
    {
174 1
        $registrations = $this->registrationRepository->findByMainRegistration($registration);
0 ignored issues
show
Documentation Bug introduced by
The method findByMainRegistration does not exist on object<DERHANSEN\SfEvent...RegistrationRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
175 1
        foreach ($registrations as $foundRegistration) {
176 1
            /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $foundRegistration */
177
            $foundRegistration->setConfirmed(true);
178 4
            $this->registrationRepository->update($foundRegistration);
179
        }
180
    }
181
182
    /**
183
     * Checks if the registration can be confirmed and returns an array of variables
184 4
     *
185 4
     * @param int $reguid UID of registration
186 4
     * @param string $hmac HMAC for parameters
187
     *
188 4
     * @return array
189
     */
190
    public function checkConfirmRegistration($reguid, $hmac)
191
    {
192
        /* @var $registration Registration */
193
        $registration = null;
194
        $failed = false;
195
        $messageKey = 'event.message.confirmation_successful';
196
        $titleKey = 'confirmRegistration.title.successful';
197
198 1
        if (!$this->hashService->validateHmac('reg-' . $reguid, $hmac)) {
199
            $failed = true;
200 1
            $messageKey = 'event.message.confirmation_failed_wrong_hmac';
201 1
            $titleKey = 'confirmRegistration.title.failed';
202 1
        } else {
203 1
            $registration = $this->registrationRepository->findByUid($reguid);
204 1
        }
205
206
        if (!$failed && is_null($registration)) {
207
            $failed = true;
208
            $messageKey = 'event.message.confirmation_failed_registration_not_found';
209
            $titleKey = 'confirmRegistration.title.failed';
210
        }
211
212
        if (!$failed && $registration->getConfirmationUntil() < new \DateTime()) {
213
            $failed = true;
214 4
            $messageKey = 'event.message.confirmation_failed_confirmation_until_expired';
215
            $titleKey = 'confirmRegistration.title.failed';
216
        }
217 4
218 4
        if (!$failed && $registration->getConfirmed() === true) {
219 4
            $failed = true;
220 4
            $messageKey = 'event.message.confirmation_failed_already_confirmed';
221
            $titleKey = 'confirmRegistration.title.failed';
222 4
        }
223 1
224 1
        if (!$failed && $registration->getWaitlist()) {
225 1
            $messageKey = 'event.message.confirmation_waitlist_successful';
226 1
            $titleKey = 'confirmRegistrationWaitlist.title.successful';
227 3
        }
228
229
        return [
230 4
            $failed,
231 1
            $registration,
232 1
            $messageKey,
233 1
            $titleKey
234 1
        ];
235
    }
236 4
237 1
    /**
238 1
     * Cancels all depending registrations based on the given main registration
239 1
     *
240 1
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
241
     *
242 4
     * @return void
243 4
     */
244 4
    public function cancelDependingRegistrations($registration)
245 1
    {
246 1
        $registrations = $this->registrationRepository->findByMainRegistration($registration);
0 ignored issues
show
Documentation Bug introduced by
The method findByMainRegistration does not exist on object<DERHANSEN\SfEvent...RegistrationRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
247 1
        foreach ($registrations as $foundRegistration) {
248 1
            $this->registrationRepository->remove($foundRegistration);
249
        }
250
    }
251 4
252 4
    /**
253 4
     * Checks if the registration can be cancelled and returns an array of variables
254
     *
255 4
     * @param int $reguid UID of registration
256
     * @param string $hmac HMAC for parameters
257
     *
258
     * @return array
259
     */
260
    public function checkCancelRegistration($reguid, $hmac)
261
    {
262
        /* @var $registration Registration */
263 5
        $registration = null;
264
        $failed = false;
265 5
        $messageKey = 'event.message.cancel_successful';
266 1
        $titleKey = 'cancelRegistration.title.successful';
267
268 4
        if (!$this->hashService->validateHmac('reg-' . $reguid, $hmac)) {
269
            $failed = true;
270
            $messageKey = 'event.message.cancel_failed_wrong_hmac';
271
            $titleKey = 'cancelRegistration.title.failed';
272
        } else {
273
            $registration = $this->registrationRepository->findByUid($reguid);
274
        }
275
276
        if (!$failed && is_null($registration)) {
277
            $failed = true;
278
            $messageKey = 'event.message.cancel_failed_registration_not_found_or_cancelled';
279
            $titleKey = 'cancelRegistration.title.failed';
280
        }
281
282 19
        if (!$failed && $registration->getEvent()->getEnableCancel() === false) {
283
            $failed = true;
284 19
            $messageKey = 'event.message.confirmation_failed_cancel_disabled';
285 19
            $titleKey = 'cancelRegistration.title.failed';
286 2
        }
287 2
288 19
        if (!$failed && $registration->getEvent()->getCancelDeadline() > 0
289 2
            && $registration->getEvent()->getCancelDeadline() < new \DateTime()
290 2
        ) {
291 17
            $failed = true;
292 2
            $messageKey = 'event.message.cancel_failed_deadline_expired';
293 2
            $titleKey = 'cancelRegistration.title.failed';
294 15
        }
295 13
296 13
        if (!$failed && $registration->getEvent()->getStartdate() < new \DateTime()) {
297 2
            $failed = true;
298 2
            $messageKey = 'event.message.cancel_failed_event_started';
299 13
            $titleKey = 'cancelRegistration.title.failed';
300 11
        }
301 11
302 2
        return [
303 2
            $failed,
304 11
            $registration,
305 2
            $messageKey,
306 2
            $titleKey
307 9
        ];
308 2
    }
309 7
310 2
    /**
311 2
     * Returns the current frontend user object if available
312 7
     *
313 5
     * @return \TYPO3\CMS\Extbase\Domain\Model\FrontendUser|null
314 5
     */
315 1
    public function getCurrentFeUserObject()
316 1
    {
317 19
        if (isset($GLOBALS['TSFE']->fe_user->user['uid'])) {
318
            return $this->frontendUserRepository->findByUid($GLOBALS['TSFE']->fe_user->user['uid']);
319
        } else {
320
            return null;
321
        }
322
    }
323
324
    /**
325
     * Checks, if the registration can successfully be created. Note, that
326
     * $result is passed by reference!
327 2
     *
328
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
329 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
330 2
     * @param int $result Result
331
     *
332
     * @return bool
333
     */
334
    public function checkRegistrationSuccess($event, $registration, &$result)
335
    {
336
        $success = true;
337
        if ($event->getEnableRegistration() === false) {
338
            $success = false;
339 2
            $result = RegistrationResult::REGISTRATION_NOT_ENABLED;
340
        } elseif ($event->getRegistrationDeadline() != null && $event->getRegistrationDeadline() < new \DateTime()) {
341 2
            $success = false;
342 1
            $result = RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED;
343
        } elseif ($event->getStartdate() < new \DateTime()) {
344
            $success = false;
345
            $result = RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED;
346 1
        } elseif ($event->getRegistration()->count() >= $event->getMaxParticipants()
347 1
            && $event->getMaxParticipants() > 0 && !$event->getEnableWaitlist()
348 1
        ) {
349
            $success = false;
350
            $result = RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS;
351
        } elseif ($event->getFreePlaces() < $registration->getAmountOfRegistrations()
352
            && $event->getMaxParticipants() > 0 && !$event->getEnableWaitlist()
353
        ) {
354
            $success = false;
355
            $result = RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES;
356
        } elseif ($event->getMaxRegistrationsPerUser() < $registration->getAmountOfRegistrations()) {
357
            $success = false;
358
            $result = RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED;
359
        } elseif ($event->getUniqueEmailCheck() &&
360
            $this->emailNotUnique($event, $registration->getEmail())
361
        ) {
362 7
            $success = false;
363
            $result = RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE;
364 7
        } elseif ($event->getRegistration()->count() >= $event->getMaxParticipants()
365 3
            && $event->getMaxParticipants() > 0 && $event->getEnableWaitlist()
366
        ) {
367
            $result = RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST;
368 4
        }
369 4
        return $success;
370 1
    }
371 4
372 2
    /**
373 2
     * Returns if the given e-mail is registered to the given event
374 4
     *
375
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
376
     * @param string $email
377
     * @return bool
378
     */
379
    protected function emailNotUnique($event, $email)
380
    {
381
        $registrations = $this->registrationRepository->findEventRegistrationsByEmail($event, $email);
382
        return $registrations->count() >= 1;
383
    }
384
385
    /**
386
     * Returns, if payment redirect for the payment method is enabled
387
     *
388
     * @param Registration $registration
389
     * @return bool
390
     */
391
    public function redirectPaymentEnabled($registration)
392
    {
393
        if ($registration->getEvent()->getEnablePayment() === false) {
394
            return false;
395
        }
396
397
        /** @var AbstractPayment $paymentInstance */
398
        $paymentInstance = $this->paymentService->getPaymentInstance($registration->getPaymentmethod());
399
        if ($paymentInstance !== null && $paymentInstance->isRedirectEnabled()) {
400
            return true;
401
        } else {
402
            return false;
403
        }
404
    }
405
406
    /**
407
     * Returns if the given amount of registrations for the event will be registrations for the waitlist
408
     * (depending on the total amount of registrations and free places)
409
     *
410
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
411
     * @param int $amountOfRegistrations
412
     * @return bool
413
     */
414
    public function isWaitlistRegistration($event, $amountOfRegistrations)
415
    {
416
        if ($event->getMaxParticipants() === 0 || !$event->getEnableWaitlist()) {
417
            return false;
418
        }
419
420
        $result = false;
421
        if (($event->getFreePlaces() > 0 && $event->getFreePlaces() < $amountOfRegistrations)
422
            || $event->getFreePlaces() <= 0) {
423
            $result = true;
424
        }
425
        return $result;
426
    }
427
}
428