Completed
Push — development ( 25c3bd...46781f )
by Torben
06:55
created

RegistrationService::handleExpiredRegistrations()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
ccs 5
cts 5
cp 1
cc 4
nc 4
nop 1
crap 4
1
<?php
2
namespace DERHANSEN\SfEventMgt\Service;
3
4
/*
5
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.txt file that was distributed with this source code.
9
 */
10
11
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
12
use DERHANSEN\SfEventMgt\Payment\AbstractPayment;
13
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
14
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
15
16
/**
17
 * RegistrationService
18
 *
19
 * @author Torben Hansen <[email protected]>
20
 */
21
class RegistrationService
22
{
23
    /**
24
     * The object manager
25
     *
26
     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
27
     * */
28
    protected $objectManager;
29
30
    /**
31
     * RegistrationRepository
32
     *
33
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
34
     * */
35
    protected $registrationRepository;
36
37
    /**
38
     * FrontendUserRepository
39
     *
40
     * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
41
     * */
42
    protected $frontendUserRepository;
43
44
    /**
45
     * Hash Service
46
     *
47
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
48
     * */
49
    protected $hashService;
50
51
    /**
52
     * Payment Service
53
     *
54
     * @var \DERHANSEN\SfEventMgt\Service\PaymentService
55
     * */
56
    protected $paymentService;
57
58
    /**
59
     * DI for $frontendUserRepository
60
     *
61
     * @param \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
62
     */
63
    public function injectFrontendUserRepository(
64
        \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
65
    ) {
66
        $this->frontendUserRepository = $frontendUserRepository;
67
    }
68
69
    /**
70
     * DI for $hashService
71
     *
72
     * @param \TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService
73
     */
74
    public function injectHashService(\TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService)
75
    {
76
        $this->hashService = $hashService;
77
    }
78 2
79
    /**
80 2
     * DI for $objectManager
81 2
     *
82 2
     * @param \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
83
     */
84 2
    public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager)
85 1
    {
86 1
        $this->objectManager = $objectManager;
87 1
    }
88 1
89
    /**
90 2
     * DI for $paymentService
91 2
     *
92 2
     * @param \DERHANSEN\SfEventMgt\Service\PaymentService $paymentService
93
     */
94
    public function injectPaymentService(\DERHANSEN\SfEventMgt\Service\PaymentService $paymentService)
95
    {
96
        $this->paymentService = $paymentService;
97
    }
98
99
    /**
100
     * DI for $registrationRepository
101
     *
102 1
     * @param \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
103
     */
104 1
    public function injectRegistrationRepository(
105 1
        \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
106
    ) {
107 1
        $this->registrationRepository = $registrationRepository;
108 1
    }
109 1
110 1
    /**
111 1
     * Duplicates (all public accessable properties) the given registration the
112 1
     * amount of times configured in amountOfRegistrations
113 1
     *
114 1
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
115 1
     *
116 1
     * @return void
117 1
     */
118
    public function createDependingRegistrations($registration)
119
    {
120
        $registrations = $registration->getAmountOfRegistrations();
121
        for ($i = 1; $i <= $registrations - 1; $i++) {
122
            /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $newReg */
123
            $newReg = $this->objectManager->get(Registration::class);
124
            $properties = ObjectAccess::getGettableProperties($registration);
125
            foreach ($properties as $propertyName => $propertyValue) {
126 1
                ObjectAccess::setProperty($newReg, $propertyName, $propertyValue);
127
            }
128 1
            $newReg->setMainRegistration($registration);
129 1
            $newReg->setAmountOfRegistrations(1);
130
            $newReg->setIgnoreNotifications(true);
131 1
            $this->registrationRepository->add($newReg);
132 1
        }
133 1
    }
134 1
135
    /**
136
     * Confirms all depending registrations based on the given main registration
137
     *
138
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
139
     *
140
     * @return void
141
     */
142
    public function confirmDependingRegistrations($registration)
143
    {
144 4
        $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...
145
        foreach ($registrations as $foundRegistration) {
146
            /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $foundRegistration */
147 4
            $foundRegistration->setConfirmed(true);
148 4
            $this->registrationRepository->update($foundRegistration);
149 4
        }
150 4
    }
151
152 4
    /**
153 1
     * Checks if the registration can be confirmed and returns an array of variables
154 1
     *
155 1
     * @param int $reguid UID of registration
156 1
     * @param string $hmac HMAC for parameters
157 3
     *
158
     * @return array
159
     */
160 4
    public function checkConfirmRegistration($reguid, $hmac)
161 1
    {
162 1
        /* @var $registration Registration */
163 1
        $registration = null;
164 1
        $failed = false;
165
        $messageKey = 'event.message.confirmation_successful';
166 4
        $titleKey = 'confirmRegistration.title.successful';
167 1
168 1
        if (!$this->hashService->validateHmac('reg-' . $reguid, $hmac)) {
169 1
            $failed = true;
170 1
            $messageKey = 'event.message.confirmation_failed_wrong_hmac';
171
            $titleKey = 'confirmRegistration.title.failed';
172 4
        } else {
173 1
            $registration = $this->registrationRepository->findByUid($reguid);
174 1
        }
175 1
176 1
        if (!$failed && is_null($registration)) {
177
            $failed = true;
178 4
            $messageKey = 'event.message.confirmation_failed_registration_not_found';
179
            $titleKey = 'confirmRegistration.title.failed';
180
        }
181
182
        if (!$failed && $registration->getConfirmationUntil() < new \DateTime()) {
183
            $failed = true;
184 4
            $messageKey = 'event.message.confirmation_failed_confirmation_until_expired';
185 4
            $titleKey = 'confirmRegistration.title.failed';
186 4
        }
187
188 4
        if (!$failed && $registration->getConfirmed() === true) {
189
            $failed = true;
190
            $messageKey = 'event.message.confirmation_failed_already_confirmed';
191
            $titleKey = 'confirmRegistration.title.failed';
192
        }
193
194
        if (!$failed && $registration->getWaitlist()) {
195
            $messageKey = 'event.message.confirmation_waitlist_successful';
196
            $titleKey = 'confirmRegistrationWaitlist.title.successful';
197
        }
198 1
199
        return [
200 1
            $failed,
201 1
            $registration,
202 1
            $messageKey,
203 1
            $titleKey
204 1
        ];
205
    }
206
207
    /**
208
     * Cancels all depending registrations based on the given main registration
209
     *
210
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
211
     *
212
     * @return void
213
     */
214 4
    public function cancelDependingRegistrations($registration)
215
    {
216
        $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...
217 4
        foreach ($registrations as $foundRegistration) {
218 4
            $this->registrationRepository->remove($foundRegistration);
219 4
        }
220 4
    }
221
222 4
    /**
223 1
     * Checks if the registration can be cancelled and returns an array of variables
224 1
     *
225 1
     * @param int $reguid UID of registration
226 1
     * @param string $hmac HMAC for parameters
227 3
     *
228
     * @return array
229
     */
230 4
    public function checkCancelRegistration($reguid, $hmac)
231 1
    {
232 1
        /* @var $registration Registration */
233 1
        $registration = null;
234 1
        $failed = false;
235
        $messageKey = 'event.message.cancel_successful';
236 4
        $titleKey = 'cancelRegistration.title.successful';
237 1
238 1
        if (!$this->hashService->validateHmac('reg-' . $reguid, $hmac)) {
239 1
            $failed = true;
240 1
            $messageKey = 'event.message.cancel_failed_wrong_hmac';
241
            $titleKey = 'cancelRegistration.title.failed';
242 4
        } else {
243 4
            $registration = $this->registrationRepository->findByUid($reguid);
244 4
        }
245 1
246 1
        if (!$failed && is_null($registration)) {
247 1
            $failed = true;
248 1
            $messageKey = 'event.message.cancel_failed_registration_not_found_or_cancelled';
249
            $titleKey = 'cancelRegistration.title.failed';
250
        }
251 4
252 4
        if (!$failed && $registration->getEvent()->getEnableCancel() === false) {
253 4
            $failed = true;
254
            $messageKey = 'event.message.confirmation_failed_cancel_disabled';
255 4
            $titleKey = 'cancelRegistration.title.failed';
256
        }
257
258
        if (!$failed && $registration->getEvent()->getCancelDeadline() > 0
259
            && $registration->getEvent()->getCancelDeadline() < new \DateTime()
260
        ) {
261
            $failed = true;
262
            $messageKey = 'event.message.cancel_failed_deadline_expired';
263 5
            $titleKey = 'cancelRegistration.title.failed';
264
        }
265 5
266 1
        if (!$failed && $registration->getEvent()->getStartdate() < new \DateTime()) {
267
            $failed = true;
268 4
            $messageKey = 'event.message.cancel_failed_event_started';
269
            $titleKey = 'cancelRegistration.title.failed';
270
        }
271
272
        return [
273
            $failed,
274
            $registration,
275
            $messageKey,
276
            $titleKey
277
        ];
278
    }
279
280
    /**
281
     * Returns the current frontend user object if available
282 19
     *
283
     * @return mixed \TYPO3\CMS\Extbase\Domain\Model\FrontendUser|null
284 19
     */
285 19
    public function getCurrentFeUserObject()
286 2
    {
287 2
        if (isset($GLOBALS['TSFE']->fe_user->user['uid'])) {
288 19
            return $this->frontendUserRepository->findByUid($GLOBALS['TSFE']->fe_user->user['uid']);
289 2
        }
290 2
291 17
        return null;
292 2
    }
293 2
294 15
    /**
295 13
     * Checks, if the registration can successfully be created. Note, that
296 13
     * $result is passed by reference!
297 2
     *
298 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
299 13
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
300 11
     * @param int $result Result
301 11
     *
302 2
     * @return bool
303 2
     */
304 11
    public function checkRegistrationSuccess($event, $registration, &$result)
305 2
    {
306 2
        $success = true;
307 9
        if ($event->getEnableRegistration() === false) {
308 2
            $success = false;
309 7
            $result = RegistrationResult::REGISTRATION_NOT_ENABLED;
310 2
        } elseif ($event->getRegistrationDeadline() != null && $event->getRegistrationDeadline() < new \DateTime()) {
311 2
            $success = false;
312 7
            $result = RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED;
313 5
        } elseif ($event->getStartdate() < new \DateTime()) {
314 5
            $success = false;
315 1
            $result = RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED;
316 1
        } elseif ($event->getRegistration()->count() >= $event->getMaxParticipants()
317 19
            && $event->getMaxParticipants() > 0 && !$event->getEnableWaitlist()
318
        ) {
319
            $success = false;
320
            $result = RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS;
321
        } elseif ($event->getFreePlaces() < $registration->getAmountOfRegistrations()
322
            && $event->getMaxParticipants() > 0 && !$event->getEnableWaitlist()
323
        ) {
324
            $success = false;
325
            $result = RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES;
326
        } elseif ($event->getMaxRegistrationsPerUser() < $registration->getAmountOfRegistrations()) {
327 2
            $success = false;
328
            $result = RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED;
329 2
        } elseif ($event->getUniqueEmailCheck() &&
330 2
            $this->emailNotUnique($event, $registration->getEmail())
331
        ) {
332
            $success = false;
333
            $result = RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE;
334
        } elseif ($event->getRegistration()->count() >= $event->getMaxParticipants()
335
            && $event->getMaxParticipants() > 0 && $event->getEnableWaitlist()
336
        ) {
337
            $result = RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST;
338
        }
339 2
340
        return $success;
341 2
    }
342 1
343
    /**
344
     * Returns if the given e-mail is registered to the given event
345
     *
346 1
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
347 1
     * @param string $email
348 1
     * @return bool
349
     */
350
    protected function emailNotUnique($event, $email)
351
    {
352
        $registrations = $this->registrationRepository->findEventRegistrationsByEmail($event, $email);
353
354
        return $registrations->count() >= 1;
355
    }
356
357
    /**
358
     * Returns, if payment redirect for the payment method is enabled
359
     *
360
     * @param Registration $registration
361
     * @return bool
362 7
     */
363
    public function redirectPaymentEnabled($registration)
364 7
    {
365 3
        if ($registration->getEvent()->getEnablePayment() === false) {
366
            return false;
367
        }
368 4
369 4
        /** @var AbstractPayment $paymentInstance */
370 1
        $paymentInstance = $this->paymentService->getPaymentInstance($registration->getPaymentmethod());
371 4
        if ($paymentInstance !== null && $paymentInstance->isRedirectEnabled()) {
372 2
            return true;
373 2
        }
374 4
375
        return false;
376
    }
377
378
    /**
379
     * Returns if the given amount of registrations for the event will be registrations for the waitlist
380
     * (depending on the total amount of registrations and free places)
381
     *
382
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
383
     * @param int $amountOfRegistrations
384
     * @return bool
385
     */
386
    public function isWaitlistRegistration($event, $amountOfRegistrations)
387
    {
388
        if ($event->getMaxParticipants() === 0 || !$event->getEnableWaitlist()) {
389
            return false;
390
        }
391
392
        $result = false;
393
        if (($event->getFreePlaces() > 0 && $event->getFreePlaces() < $amountOfRegistrations)
394
            || $event->getFreePlaces() <= 0) {
395
            $result = true;
396
        }
397
398
        return $result;
399
    }
400
}
401