Completed
Push — task/821-remove-lang ( 1a66a2 )
by Torben
43:13
created

updateRegistrationFieldValueLanguage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
5
 *
6
 * For the full copyright and license information, please read the
7
 * LICENSE.txt file that was distributed with this source code.
8
 */
9
10
namespace DERHANSEN\SfEventMgt\Service;
11
12
use DERHANSEN\SfEventMgt\Domain\Model\Event;
13
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
14
use DERHANSEN\SfEventMgt\Event\AfterRegistrationMovedFromWaitlist;
15
use DERHANSEN\SfEventMgt\Payment\AbstractPayment;
16
use DERHANSEN\SfEventMgt\Utility\MessageType;
17
use DERHANSEN\SfEventMgt\Utility\RegistrationResult;
18
use Psr\EventDispatcher\EventDispatcherInterface;
19
use TYPO3\CMS\Core\Database\Connection;
20
use TYPO3\CMS\Core\Database\ConnectionPool;
21
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
22
use TYPO3\CMS\Core\Utility\GeneralUtility;
23
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
24
25
/**
26
 * RegistrationService
27
 *
28
 * @author Torben Hansen <[email protected]>
29
 */
30
class RegistrationService
31
{
32
    /**
33
     * The object manager
34
     *
35
     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
36
     * */
37
    protected $objectManager;
38
39
    /**
40
     * @var EventDispatcherInterface
41
     */
42
    protected $eventDispatcher;
43
44
    /**
45
     * RegistrationRepository
46
     *
47
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
48
     * */
49
    protected $registrationRepository;
50
51
    /**
52
     * FrontendUserRepository
53
     *
54
     * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
55
     * */
56
    protected $frontendUserRepository;
57
58
    /**
59
     * Hash Service
60
     *
61
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
62
     * */
63
    protected $hashService;
64
65
    /**
66
     * Payment Service
67
     *
68
     * @var \DERHANSEN\SfEventMgt\Service\PaymentService
69
     * */
70
    protected $paymentService;
71
72
    /**
73
     * Notification Service
74
     *
75
     * @var \DERHANSEN\SfEventMgt\Service\NotificationService
76
     */
77
    protected $notificationService;
78
79
    /**
80
     * DI for $frontendUserRepository
81
     *
82
     * @param \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
83
     */
84
    public function injectFrontendUserRepository(
85
        \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
86
    ) {
87
        $this->frontendUserRepository = $frontendUserRepository;
88
    }
89
90
    /**
91
     * DI for $hashService
92
     *
93
     * @param \TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService
94
     */
95
    public function injectHashService(\TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService)
96
    {
97
        $this->hashService = $hashService;
98
    }
99
100
    /**
101
     * @param \DERHANSEN\SfEventMgt\Service\NotificationService $notificationService
102
     */
103
    public function injectNotificationService(\DERHANSEN\SfEventMgt\Service\NotificationService $notificationService)
104
    {
105
        $this->notificationService = $notificationService;
106
    }
107
108
    /**
109
     * DI for $objectManager
110
     *
111
     * @param \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
112
     */
113
    public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager)
114
    {
115
        $this->objectManager = $objectManager;
116
    }
117
118
    /**
119
     * @param EventDispatcherInterface $eventDispatcher
120
     */
121
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher)
122
    {
123
        $this->eventDispatcher = $eventDispatcher;
124
    }
125
126
    /**
127
     * DI for $paymentService
128
     *
129
     * @param \DERHANSEN\SfEventMgt\Service\PaymentService $paymentService
130
     */
131
    public function injectPaymentService(\DERHANSEN\SfEventMgt\Service\PaymentService $paymentService)
132
    {
133
        $this->paymentService = $paymentService;
134
    }
135
136
    /**
137
     * DI for $registrationRepository
138
     *
139
     * @param \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
140
     */
141
    public function injectRegistrationRepository(
142
        \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
143
    ) {
144
        $this->registrationRepository = $registrationRepository;
145
    }
146
147
    /**
148
     * Duplicates (all public accessable properties) the given registration the
149
     * amount of times configured in amountOfRegistrations
150
     *
151
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
152
     */
153
    public function createDependingRegistrations($registration)
154
    {
155
        $registrations = $registration->getAmountOfRegistrations();
156
        for ($i = 1; $i <= $registrations - 1; $i++) {
157
            /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $newReg */
158
            $newReg = $this->objectManager->get(Registration::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
159
            $properties = ObjectAccess::getGettableProperties($registration);
0 ignored issues
show
Documentation introduced by
$registration is of type object<DERHANSEN\SfEvent...ain\Model\Registration>, but the function expects a object<TYPO3\CMS\Extbase\Reflection\object>.

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...
160
            foreach ($properties as $propertyName => $propertyValue) {
161
                ObjectAccess::setProperty($newReg, $propertyName, $propertyValue);
162
            }
163
            $newReg->setMainRegistration($registration);
164
            $newReg->setAmountOfRegistrations(1);
165
            $newReg->setIgnoreNotifications(true);
166
            $this->registrationRepository->add($newReg);
167
        }
168
    }
169
170
    /**
171
     * Confirms all depending registrations based on the given main registration
172
     *
173
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
174
     */
175
    public function confirmDependingRegistrations($registration)
176
    {
177
        $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...
178
        foreach ($registrations as $foundRegistration) {
179
            /** @var \DERHANSEN\SfEventMgt\Domain\Model\Registration $foundRegistration */
180
            $foundRegistration->setConfirmed(true);
181
            $this->registrationRepository->update($foundRegistration);
182
        }
183
    }
184
185
    /**
186
     * Checks if the registration can be confirmed and returns an array of variables
187
     *
188
     * @param int $reguid UID of registration
189
     * @param string $hmac HMAC for parameters
190
     *
191
     * @return array
192
     */
193
    public function checkConfirmRegistration($reguid, $hmac)
194
    {
195
        /* @var $registration Registration */
196
        $registration = null;
197
        $failed = false;
198
        $messageKey = 'event.message.confirmation_successful';
199
        $titleKey = 'confirmRegistration.title.successful';
200
201
        if (!$this->hashService->validateHmac('reg-' . $reguid, $hmac)) {
202
            $failed = true;
203
            $messageKey = 'event.message.confirmation_failed_wrong_hmac';
204
            $titleKey = 'confirmRegistration.title.failed';
205
        } else {
206
            $registration = $this->registrationRepository->findByUid($reguid);
207
        }
208
209
        if (!$failed && is_null($registration)) {
210
            $failed = true;
211
            $messageKey = 'event.message.confirmation_failed_registration_not_found';
212
            $titleKey = 'confirmRegistration.title.failed';
213
        }
214
215
        if (!$failed && $registration->getConfirmationUntil() < new \DateTime()) {
216
            $failed = true;
217
            $messageKey = 'event.message.confirmation_failed_confirmation_until_expired';
218
            $titleKey = 'confirmRegistration.title.failed';
219
        }
220
221
        if (!$failed && $registration->getConfirmed() === true) {
222
            $failed = true;
223
            $messageKey = 'event.message.confirmation_failed_already_confirmed';
224
            $titleKey = 'confirmRegistration.title.failed';
225
        }
226
227
        if (!$failed && $registration->getWaitlist()) {
228
            $messageKey = 'event.message.confirmation_waitlist_successful';
229
            $titleKey = 'confirmRegistrationWaitlist.title.successful';
230
        }
231
232
        return [
233
            $failed,
234
            $registration,
235
            $messageKey,
236
            $titleKey
237
        ];
238
    }
239
240
    /**
241
     * Cancels all depending registrations based on the given main registration
242
     *
243
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
244
     */
245
    public function cancelDependingRegistrations($registration)
246
    {
247
        $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...
248
        foreach ($registrations as $foundRegistration) {
249
            $this->registrationRepository->remove($foundRegistration);
250
        }
251
    }
252
253
    /**
254
     * Checks if the registration can be cancelled and returns an array of variables
255
     *
256
     * @param int $reguid UID of registration
257
     * @param string $hmac HMAC for parameters
258
     *
259
     * @return array
260
     */
261
    public function checkCancelRegistration($reguid, $hmac)
262
    {
263
        /* @var $registration Registration */
264
        $registration = null;
265
        $failed = false;
266
        $messageKey = 'event.message.cancel_successful';
267
        $titleKey = 'cancelRegistration.title.successful';
268
269
        if (!$this->hashService->validateHmac('reg-' . $reguid, $hmac)) {
270
            $failed = true;
271
            $messageKey = 'event.message.cancel_failed_wrong_hmac';
272
            $titleKey = 'cancelRegistration.title.failed';
273
        } else {
274
            $registration = $this->registrationRepository->findByUid($reguid);
275
        }
276
277
        if (!$failed && is_null($registration)) {
278
            $failed = true;
279
            $messageKey = 'event.message.cancel_failed_registration_not_found_or_cancelled';
280
            $titleKey = 'cancelRegistration.title.failed';
281
        }
282
283
        if (!$failed && $registration->getEvent()->getEnableCancel() === false) {
284
            $failed = true;
285
            $messageKey = 'event.message.confirmation_failed_cancel_disabled';
286
            $titleKey = 'cancelRegistration.title.failed';
287
        }
288
289
        if (!$failed && $registration->getEvent()->getCancelDeadline() > 0
290
            && $registration->getEvent()->getCancelDeadline() < new \DateTime()
291
        ) {
292
            $failed = true;
293
            $messageKey = 'event.message.cancel_failed_deadline_expired';
294
            $titleKey = 'cancelRegistration.title.failed';
295
        }
296
297
        if (!$failed && $registration->getEvent()->getStartdate() < new \DateTime()) {
298
            $failed = true;
299
            $messageKey = 'event.message.cancel_failed_event_started';
300
            $titleKey = 'cancelRegistration.title.failed';
301
        }
302
303
        return [
304
            $failed,
305
            $registration,
306
            $messageKey,
307
            $titleKey
308
        ];
309
    }
310
311
    /**
312
     * Returns the current frontend user object if available
313
     *
314
     * @return mixed \TYPO3\CMS\Extbase\Domain\Model\FrontendUser|null
315
     */
316
    public function getCurrentFeUserObject()
317
    {
318
        if (isset($GLOBALS['TSFE']->fe_user->user['uid'])) {
319
            return $this->frontendUserRepository->findByUid($GLOBALS['TSFE']->fe_user->user['uid']);
320
        }
321
322
        return null;
323
    }
324
325
    /**
326
     * Checks, if the registration can successfully be created. Note, that
327
     * $result is passed by reference!
328
     *
329
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
330
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration Registration
331
     * @param int $result Result
332
     *
333
     * @return array
334
     */
335
    public function checkRegistrationSuccess($event, $registration, $result)
336
    {
337
        $success = true;
338
        if ($event->getEnableRegistration() === false) {
339
            $success = false;
340
            $result = RegistrationResult::REGISTRATION_NOT_ENABLED;
341
        } elseif ($event->getRegistrationDeadline() != null && $event->getRegistrationDeadline() < new \DateTime()) {
342
            $success = false;
343
            $result = RegistrationResult::REGISTRATION_FAILED_DEADLINE_EXPIRED;
344
        } elseif ($event->getStartdate() < new \DateTime()) {
345
            $success = false;
346
            $result = RegistrationResult::REGISTRATION_FAILED_EVENT_EXPIRED;
347
        } elseif ($event->getRegistrations()->count() >= $event->getMaxParticipants()
348
            && $event->getMaxParticipants() > 0 && !$event->getEnableWaitlist()
349
        ) {
350
            $success = false;
351
            $result = RegistrationResult::REGISTRATION_FAILED_MAX_PARTICIPANTS;
352
        } elseif ($event->getFreePlaces() < $registration->getAmountOfRegistrations()
353
            && $event->getMaxParticipants() > 0 && !$event->getEnableWaitlist()
354
        ) {
355
            $success = false;
356
            $result = RegistrationResult::REGISTRATION_FAILED_NOT_ENOUGH_FREE_PLACES;
357
        } elseif ($event->getMaxRegistrationsPerUser() < $registration->getAmountOfRegistrations()) {
358
            $success = false;
359
            $result = RegistrationResult::REGISTRATION_FAILED_MAX_AMOUNT_REGISTRATIONS_EXCEEDED;
360
        } elseif ($event->getUniqueEmailCheck() &&
361
            $this->emailNotUnique($event, $registration->getEmail())
362
        ) {
363
            $success = false;
364
            $result = RegistrationResult::REGISTRATION_FAILED_EMAIL_NOT_UNIQUE;
365
        } elseif ($event->getRegistrations()->count() >= $event->getMaxParticipants()
366
            && $event->getMaxParticipants() > 0 && $event->getEnableWaitlist()
367
        ) {
368
            $result = RegistrationResult::REGISTRATION_SUCCESSFUL_WAITLIST;
369
        }
370
371
        return [$success, $result];
372
    }
373
374
    /**
375
     * Returns if the given email is registered to the given event
376
     *
377
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
378
     * @param string $email
379
     * @return bool
380
     */
381
    protected function emailNotUnique($event, $email)
382
    {
383
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
384
            ->getQueryBuilderForTable('tx_sfeventmgt_domain_model_registration');
385
        $queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
386
        $registrations = $queryBuilder->count('email')
387
            ->from('tx_sfeventmgt_domain_model_registration')
388
            ->where(
389
                $queryBuilder->expr()->eq(
390
                    'event',
391
                    $queryBuilder->createNamedParameter($event->getUid(), Connection::PARAM_INT)
392
                ),
393
                $queryBuilder->expr()->eq(
394
                    'email',
395
                    $queryBuilder->createNamedParameter($email, Connection::PARAM_STR)
396
                )
397
            )
398
            ->execute()
399
            ->fetchColumn();
400
401
        return $registrations >= 1;
402
    }
403
404
    /**
405
     * Returns, if payment redirect for the payment method is enabled
406
     *
407
     * @param Registration $registration
408
     * @return bool
409
     */
410
    public function redirectPaymentEnabled($registration)
411
    {
412
        if ($registration->getEvent()->getEnablePayment() === false) {
413
            return false;
414
        }
415
416
        /** @var AbstractPayment $paymentInstance */
417
        $paymentInstance = $this->paymentService->getPaymentInstance($registration->getPaymentmethod());
418
        if ($paymentInstance !== null && $paymentInstance->isRedirectEnabled()) {
419
            return true;
420
        }
421
422
        return false;
423
    }
424
425
    /**
426
     * Returns if the given amount of registrations for the event will be registrations for the waitlist
427
     * (depending on the total amount of registrations and free places)
428
     *
429
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event
430
     * @param int $amountOfRegistrations
431
     * @return bool
432
     */
433
    public function isWaitlistRegistration($event, $amountOfRegistrations)
434
    {
435
        if ($event->getMaxParticipants() === 0 || !$event->getEnableWaitlist()) {
436
            return false;
437
        }
438
439
        $result = false;
440
        if (($event->getFreePlaces() > 0 && $event->getFreePlaces() < $amountOfRegistrations)
441
            || $event->getFreePlaces() <= 0) {
442
            $result = true;
443
        }
444
445
        return $result;
446
    }
447
448
    /**
449
     * Fixes the event uid of a registration if the event has been saved as a child of a translated event.
450
     *
451
     * Since TYPO3 9.5 (#82363), registrations for events are saved to the translated event record
452
     *
453
     * Example:
454
     *
455
     * When a registration is saved for a translated event, the registration $registration->setEvent($event) will
456
     * now save the UID of the translated event instead of the uid of the event in default language.
457
     *
458
     * This behavior breaks limitations on events (e.g. max participants). Therefore, the registration must always
459
     * be related to the default event language (Extbase behavior before TYPO3 9.5)
460
     *
461
     * @param Registration $registration
462
     * @param Event $event
463
     */
464
    public function fixRegistrationEvent(Registration $registration, Event $event)
465
    {
466
        // Early return when event is in default language
467
        if ((int)$event->_getProperty('_languageUid') === 0) {
468
            return;
469
        }
470
        $this->updateRegistrationEventUid($registration, $event);
471
        $this->updateEventRegistrationCounters($event);
472
    }
473
474
    /**
475
     * Sets the "event" field of the given registration to the uid of the given event
476
     *
477
     * @param Registration $registration
478
     * @param Event $event
479
     */
480
    protected function updateRegistrationEventUid(Registration $registration, Event $event)
481
    {
482
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
483
            ->getQueryBuilderForTable('tx_sfeventmgt_domain_model_registration');
484
        $queryBuilder->update('tx_sfeventmgt_domain_model_registration')
485
            ->set('event', $event->getUid())
486
            ->where(
487
                $queryBuilder->expr()->eq(
488
                    'uid',
489
                    $queryBuilder->createNamedParameter($registration->getUid(), Connection::PARAM_INT)
490
                )
491
            )
492
            ->execute();
493
    }
494
495
    /**
496
     * Updates registration/waitlist registration counters for the given event
497
     *
498
     * @param Event $event
499
     */
500
    protected function updateEventRegistrationCounters(Event $event)
501
    {
502
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
503
            ->getQueryBuilderForTable('tx_sfeventmgt_domain_model_event');
504
505
        $countRegistrations = $this->getEventRegistrationCount($event, 0);
506
        $countRegistrationsWaitlist = $this->getEventRegistrationCount($event, 1);
507
508
        $queryBuilder->update('tx_sfeventmgt_domain_model_event')
509
            ->set('registration', $countRegistrations)
510
            ->set('registration_waitlist', $countRegistrationsWaitlist)
511
            ->where(
512
                $queryBuilder->expr()->eq(
513
                    'uid',
514
                    $queryBuilder->createNamedParameter($event->getUid(), Connection::PARAM_INT)
515
                )
516
            )
517
            ->orWhere(
518
                $queryBuilder->expr()->eq(
519
                    'l10n_parent',
520
                    $queryBuilder->createNamedParameter($event->getUid(), Connection::PARAM_INT)
521
                )
522
            )
523
            ->execute();
524
    }
525
526
    /**
527
     * Returns the total amount of registrations/waitlist registrations for an event
528
     *
529
     * @param Event $event
530
     * @param int $waitlist
531
     * @return mixed
532
     */
533
    protected function getEventRegistrationCount(Event $event, int $waitlist = 0)
534
    {
535
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
536
            ->getQueryBuilderForTable('tx_sfeventmgt_domain_model_registration');
537
        $queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
538
539
        return $queryBuilder->count('uid')
540
            ->from('tx_sfeventmgt_domain_model_registration')
541
            ->where(
542
                $queryBuilder->expr()->eq(
543
                    'event',
544
                    $queryBuilder->createNamedParameter($event->getUid(), Connection::PARAM_INT)
545
                ),
546
                $queryBuilder->expr()->eq(
547
                    'waitlist',
548
                    $queryBuilder->createNamedParameter($waitlist, Connection::PARAM_INT)
549
                )
550
            )
551
            ->execute()
552
            ->fetchColumn();
553
    }
554
555
    /**
556
     * Handles the process of moving registration up from the waitlist.
557
     *
558
     * @param Event $event
559
     * @param array $settings
560
     */
561
    public function moveUpWaitlistRegistrations(Event $event, array $settings)
562
    {
563
        // Early return if move up not enabled, no registrations on waitlist or no free places left
564
        if (!$event->getEnableWaitlistMoveup() || $event->getRegistrationsWaitlist()->count() === 0 ||
565
            $event->getFreePlaces() === 0
566
        ) {
567
            return;
568
        }
569
570
        $keepMainRegistrationDependency = $settings['waitlist']['moveUp']['keepMainRegistrationDependency'] ?? false;
571
        $freePlaces = $event->getFreePlaces();
572
        $moveupRegistrations = $this->registrationRepository->findWaitlistMoveUpRegistrations($event);
573
574
        /** @var Registration $registration */
575
        foreach ($moveupRegistrations as $registration) {
576
            $registration->setWaitlist(false);
577
            $registration->setIgnoreNotifications(false);
578
579
            if (!(bool)$keepMainRegistrationDependency) {
580
                $registration->setMainRegistration(null);
581
            }
582
583
            $this->registrationRepository->update($registration);
584
585
            // Send messages to user and admin
586
            $this->notificationService->sendUserMessage(
587
                $event,
588
                $registration,
589
                $settings,
590
                MessageType::REGISTRATION_WAITLIST_MOVE_UP
591
            );
592
            $this->notificationService->sendAdminMessage(
593
                $registration->getEvent(),
594
                $registration,
595
                $settings,
596
                MessageType::REGISTRATION_WAITLIST_MOVE_UP
597
            );
598
599
            $this->eventDispatcher->dispatch(new AfterRegistrationMovedFromWaitlist($registration, $this));
0 ignored issues
show
Documentation introduced by
new \DERHANSEN\SfEventMg...t($registration, $this) is of type object<DERHANSEN\SfEvent...ationMovedFromWaitlist>, but the function expects a object<Psr\EventDispatcher\object>.

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...
600
601
            $freePlaces--;
602
            if ($freePlaces === 0) {
603
                break;
604
            }
605
        }
606
    }
607
}
608