Passed
Push — master ( fa0555...d6212b )
by Sylvain
08:11
created

User::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Model;
6
7
use Application\DBAL\Types\BillingTypeType;
8
use Application\DBAL\Types\BookingStatusType;
9
use Application\DBAL\Types\RelationshipType;
10
use Application\Repository\LogRepository;
11
use Application\Repository\UserRepository;
12
use Application\Traits\HasAddress;
13
use Application\Traits\HasDoorAccess;
14
use Application\Traits\HasIban;
15
use Application\Traits\HasRemarks;
16
use Cake\Chronos\Chronos;
17
use Cake\Chronos\Date;
18
use Doctrine\Common\Collections\ArrayCollection;
19
use Doctrine\Common\Collections\Collection;
20
use Doctrine\ORM\Mapping as ORM;
21
use Ecodev\Felix\Api\Exception;
22
use Ecodev\Felix\Model\CurrentUser;
23
use Ecodev\Felix\Model\Traits\HasInternalRemarks;
24
use Ecodev\Felix\Model\Traits\HasPassword;
25
use GraphQL\Doctrine\Annotation as API;
26
27
/**
28
 * User
29
 *
30
 * @ORM\Entity(repositoryClass="Application\Repository\UserRepository")
31
 * @ORM\HasLifecycleCallbacks
32
 * @ORM\AssociationOverrides({
33
 *     @ORM\AssociationOverride(name="owner", inversedBy="users")
34
 * })
35
 * @API\Sorting({
36
 *     "Application\Api\Input\Sorting\Age",
37
 *     "Application\Api\Input\Sorting\Balance",
38
 * })
39
 * @API\Filters({
40
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\HasBookingWithTaggedBookableOperatorType", type="id"),
41
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\HasBookingWithBookableOperatorType", type="id"),
42
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\EqualOperatorType", type="Money"),
43
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\GreaterOperatorType", type="Money"),
44
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\GreaterOrEqualOperatorType", type="Money"),
45
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\LessOperatorType", type="Money"),
46
 *     @API\Filter(field="balance", operator="Application\Api\Input\Operator\AccountBalance\LessOrEqualOperatorType", type="Money"),
47
 * })
48
 */
49
class User extends AbstractModel implements \Ecodev\Felix\Model\User
50
{
51
    const ROLE_ANONYMOUS = 'anonymous';
52
    const ROLE_BOOKING_ONLY = 'booking_only';
53
    const ROLE_INDIVIDUAL = 'individual';
54
    const ROLE_MEMBER = 'member';
55
    const ROLE_TRAINER = 'trainer';
56
    const ROLE_RESPONSIBLE = 'responsible';
57
    const ROLE_ADMINISTRATOR = 'administrator';
58
59
    const STATUS_INACTIVE = 'inactive';
60
    const STATUS_NEW = 'new';
61
    const STATUS_ACTIVE = 'active';
62
    const STATUS_ARCHIVED = 'archived';
63
64
    use HasDoorAccess;
65
    use HasRemarks;
66
    use HasInternalRemarks;
67
    use HasAddress;
68
    use HasIban;
69
    use HasPassword;
70
71
    /**
72
     * @var User
73
     */
74
    private static $currentUser;
75
76
    /**
77
     * Set currently logged in user
78
     * WARNING: this method should only be called from \Application\Authentication\AuthenticationListener
79
     *
80
     * @param \Application\Model\User $user
81
     */
82 196
    public static function setCurrent(?self $user): void
83
    {
84 196
        self::$currentUser = $user;
85
86
        // Initalize ACL filter with current user if a logged in one exists
87
        /** @var UserRepository $userRepository */
88 196
        $userRepository = _em()->getRepository(self::class);
89 196
        $aclFilter = $userRepository->getAclFilter();
90 196
        $aclFilter->setUser($user);
91
92 196
        CurrentUser::set($user);
93 196
    }
94
95
    /**
96
     * Returns currently logged user or null
97
     */
98 73
    public static function getCurrent(): ?self
99
    {
100 73
        return self::$currentUser;
101
    }
102
103
    /**
104
     * @var null|string
105
     *
106
     * @ORM\Column(type="string", length=50, nullable=true, unique=true)
107
     */
108
    private $login;
109
110
    /**
111
     * @var string
112
     * @ORM\Column(type="string", length=191)
113
     */
114
    private $firstName = '';
115
116
    /**
117
     * @var string
118
     * @ORM\Column(type="string", length=191)
119
     */
120
    private $lastName = '';
121
122
    /**
123
     * @var null|string
124
     * @ORM\Column(type="string", length=191, nullable=true, unique=true)
125
     */
126
    private $email;
127
128
    /**
129
     * @var string
130
     * @ORM\Column(type="UserRole", options={"default" = User::ROLE_INDIVIDUAL})
131
     */
132
    private $role = self::ROLE_INDIVIDUAL;
133
134
    /**
135
     * @var string
136
     * @ORM\Column(type="UserStatus", options={"default" = User::STATUS_NEW})
137
     */
138
    private $status = self::STATUS_NEW;
139
140
    /**
141
     * @var null|Chronos
142
     * @ORM\Column(type="datetime", nullable=true)
143
     */
144
    private $welcomeSessionDate;
145
146
    /**
147
     * @var null|Chronos
148
     * @ORM\Column(type="datetime", nullable=true)
149
     */
150
    private $resignDate;
151
152
    /**
153
     * @var int sex
154
     * @ORM\Column(type="smallint", options={"default" = 0}))
155
     */
156
    private $sex = 0;
157
158
    /**
159
     * @var string
160
     * @ORM\Column(type="string", length=25, options={"default" = ""})
161
     */
162
    private $phone = '';
163
164
    /**
165
     * @var string
166
     * @ORM\Column(type="string", length=25, options={"default" = ""})
167
     */
168
    private $mobilePhone = '';
169
170
    /**
171
     * @var string
172
     * @ORM\Column(type="string", length=25, options={"default" = ""})
173
     */
174
    private $swissSailing = '';
175
176
    /**
177
     * @var string
178
     * @ORM\Column(type="SwissSailingType", nullable=true)
179
     */
180
    private $swissSailingType;
181
182
    /**
183
     * @var string
184
     * @ORM\Column(type="SwissWindsurfType", nullable=true)
185
     */
186
    private $swissWindsurfType;
187
188
    /**
189
     * @var null|Date
190
     * @ORM\Column(type="date", nullable=true)
191
     */
192
    private $birthday;
193
194
    /**
195
     * @var bool
196
     * @ORM\Column(type="boolean", options={"default" = 0})
197
     */
198
    private $termsAgreement = false;
199
200
    /**
201
     * @var bool
202
     * @ORM\Column(type="boolean", options={"default" = 0})
203
     */
204
    private $hasInsurance = false;
205
206
    /**
207
     * @var bool
208
     * @ORM\Column(type="boolean", options={"default" = 0})
209
     */
210
    private $receivesNewsletter = false;
211
212
    /**
213
     * @var string
214
     * @ORM\Column(type="Relationship", options={"default" = RelationshipType::HOUSEHOLDER})
215
     */
216
    private $familyRelationship = RelationshipType::HOUSEHOLDER;
217
218
    /**
219
     * @var string
220
     * @ORM\Column(type="BillingType", options={"default" = BillingTypeType::ELECTRONIC})
221
     */
222
    private $billingType = BillingTypeType::ELECTRONIC;
223
224
    /**
225
     * @var Collection
226
     * @ORM\OneToMany(targetEntity="Booking", mappedBy="owner")
227
     */
228
    private $bookings;
229
230
    /**
231
     * @var Collection
232
     * @ORM\ManyToMany(targetEntity="License", mappedBy="users")
233
     */
234
    private $licenses;
235
236
    /**
237
     * @var Collection
238
     * @ORM\ManyToMany(targetEntity="UserTag", mappedBy="users")
239
     */
240
    private $userTags;
241
242
    /**
243
     * @var Collection
244
     * @ORM\OneToMany(targetEntity="Message", mappedBy="recipient")
245
     */
246
    private $messages;
247
248
    /**
249
     * There is actually 0 to 1 account, never more. And this is
250
     * enforced by DB unique constraints
251
     *
252
     * @var Collection
253
     * @ORM\OneToMany(targetEntity="Account", mappedBy="owner")
254
     */
255
    private $accounts;
256
257
    /**
258
     * @var Collection
259
     * @ORM\OneToMany(targetEntity="User", mappedBy="owner")
260
     */
261
    private $users;
262
263
    /**
264
     * Constructor
265
     *
266
     * @param string $role role for new user
267
     */
268 55
    public function __construct(string $role = self::ROLE_INDIVIDUAL)
269
    {
270 55
        $this->role = $role;
271 55
        $this->bookings = new ArrayCollection();
272 55
        $this->accounts = new ArrayCollection();
273 55
        $this->licenses = new ArrayCollection();
274 55
        $this->userTags = new ArrayCollection();
275 55
        $this->messages = new ArrayCollection();
276 55
        $this->users = new ArrayCollection();
277 55
    }
278
279
    /**
280
     * Set login (eg: johndoe)
281
     *
282
     * @API\Input(type="Login")
283
     */
284 4
    public function setLogin(string $login): void
285
    {
286 4
        $this->login = $login;
287 4
    }
288
289
    /**
290
     * Get login (eg: johndoe)
291
     *
292
     * @API\Field(type="?Login")
293
     */
294 14
    public function getLogin(): ?string
295
    {
296 14
        return $this->login;
297
    }
298
299
    /**
300
     * Set first name
301
     *
302
     * @param string $firstName
303
     */
304 10
    public function setFirstName($firstName): void
305
    {
306 10
        $this->firstName = $firstName;
307 10
    }
308
309
    /**
310
     * Get first name
311
     */
312 18
    public function getFirstName(): string
313
    {
314 18
        return (string) $this->firstName;
315
    }
316
317
    /**
318
     * Set last name
319
     *
320
     * @param string $lastName
321
     */
322 10
    public function setLastName($lastName): void
323
    {
324 10
        $this->lastName = $lastName;
325 10
    }
326
327
    /**
328
     * Get last name
329
     */
330 12
    public function getLastName(): string
331
    {
332 12
        return (string) $this->lastName;
333
    }
334
335
    /**
336
     * Get full name
337
     */
338 12
    public function getName(): string
339
    {
340 12
        return implode(' ', [$this->getFirstName(), $this->getLastName()]);
341
    }
342
343
    /**
344
     * Set email
345
     *
346
     * @API\Input(type="?Email")
347
     */
348 5
    public function setEmail(?string $email): void
349
    {
350 5
        $this->email = $email;
351 5
    }
352
353
    /**
354
     * Get email
355
     *
356
     * @API\Field(type="?Email")
357
     */
358 11
    public function getEmail(): ?string
359
    {
360 11
        return $this->email;
361
    }
362
363
    /**
364
     * Returns whether the user is administrator and thus have can do anything.
365
     *
366
     * @API\Field(type="Application\Api\Enum\UserRoleType")
367
     */
368 78
    public function getRole(): string
369
    {
370 78
        return $this->role;
371
    }
372
373
    /**
374
     * Sets the user role
375
     *
376
     * The current user is allowed to promote another user up to the same role as himself. So
377
     * a Responsible can promote a Member to Responsible. Or an Admin can promote a Individual to Admin.
378
     *
379
     * But the current user is **not** allowed to demote a user who has a higher role than himself.
380
     * That means that a Responsible cannot demote an Admin to Individual.
381
     */
382 7
    public function setRole(string $role): void
383
    {
384 7
        if ($role === $this->role) {
385 2
            return;
386
        }
387
388 5
        $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
389
        $orderedRoles = [
390 5
            self::ROLE_ANONYMOUS,
391 5
            self::ROLE_INDIVIDUAL,
392 5
            self::ROLE_MEMBER,
393 5
            self::ROLE_TRAINER,
394 5
            self::ROLE_BOOKING_ONLY,
395 5
            self::ROLE_RESPONSIBLE,
396 5
            self::ROLE_ADMINISTRATOR,
397
        ];
398
399 5
        $newFound = false;
400 5
        $oldFound = false;
401 5
        foreach ($orderedRoles as $r) {
402 5
            if ($r === $this->role) {
403 3
                $oldFound = true;
404
            }
405 5
            if ($r === $role) {
406 2
                $newFound = true;
407
            }
408
409 5
            if ($r === $currentRole) {
410 5
                break;
411
            }
412
        }
413
414 5
        if (!$newFound || !$oldFound) {
415 3
            throw new Exception($currentRole . ' is not allowed to change role from ' . $this->role . ' to ' . $role);
416
        }
417
418 2
        $this->role = $role;
419 2
    }
420
421 5
    public function setOwner(?self $owner = null): void
422
    {
423 5
        if ($owner && $owner !== $this) {
424 1
            if ($owner->getOwner() && $owner !== $owner->getOwner()) {
425
                throw new Exception('This user cannot be owned by a user who is himself owned by somebody else');
426
            }
427
428 1
            if ($this->users->count()) {
429
                throw new Exception('This user owns other users, so he cannot himself be owned by somebody else');
430
            }
431
        }
432
433 5
        if ($this->getOwner()) {
434 2
            $this->getOwner()->getEmail(); // Trigger lazy loading
435 2
            $this->getOwner()->users->removeElement($this);
436
        }
437
438 5
        parent::setOwner($owner);
439
440 5
        if ($this->getOwner()) {
441 1
            $this->getOwner()->getEmail(); // Trigger lazy loading
442 1
            $this->getOwner()->users->add($this);
443 1
            $this->setStatus($this->getOwner()->getStatus());
444
        }
445 5
    }
446
447
    /**
448
     * @API\Field(type="Application\Api\Enum\UserStatusType")
449
     */
450 3
    public function getStatus(): string
451
    {
452 3
        return $this->status;
453
    }
454
455
    /**
456
     * @API\Input(type="Application\Api\Enum\UserStatusType")
457
     */
458 10
    public function setStatus(string $newStatus): void
459
    {
460 10
        if ($newStatus === self::STATUS_ARCHIVED && $this->status !== self::STATUS_ARCHIVED) {
461 1
            $this->setResignDate(Chronos::NOW());
462 9
        } elseif ($this->status === self::STATUS_ARCHIVED && $newStatus !== self::STATUS_ARCHIVED) {
463
            $this->setResignDate(null);
464
        }
465
466 10
        $this->status = $newStatus;
467 10
        $this->revokeToken();
468
469 10
        foreach ($this->users as $user) {
470 1
            if ($user !== $this) {
471
                $user->setStatus($newStatus);
472
            }
473
        }
474 10
    }
475
476
    /**
477
     * Whether this user is a family owner or not
478
     *
479
     * This is used for our internal logic and should
480
     * NEVER be related to `familyRelationship`. That field
481
     * is purely informative for humans.
482
     */
483 1
    public function isFamilyOwner(): bool
484
    {
485 1
        return !$this->getOwner() || $this->getOwner() === $this;
486
    }
487
488 1
    public function initialize(): void
489
    {
490 1
        $this->role = self::ROLE_MEMBER; // Bypass security
491 1
        $this->setStatus(self::STATUS_NEW);
492 1
    }
493
494
    public function getPhone(): string
495
    {
496
        return $this->phone;
497
    }
498
499
    public function setPhone(string $phone): void
500
    {
501
        $this->phone = $phone;
502
    }
503
504
    public function getMobilePhone(): string
505
    {
506
        return $this->mobilePhone;
507
    }
508
509 1
    public function setMobilePhone(string $mobilePhone): void
510
    {
511 1
        $this->mobilePhone = $mobilePhone;
512 1
    }
513
514
    public function getBirthday(): ?Date
515
    {
516
        return $this->birthday;
517
    }
518
519 1
    public function setBirthday(?Date $birthday): void
520
    {
521 1
        $this->birthday = $birthday;
522 1
    }
523
524
    /**
525
     * return null|int
526
     */
527
    public function getAge(): ?int
528
    {
529
        if ($this->birthday) {
530
            return (new Date())->diffInYears($this->birthday);
531
        }
532
533
        return null;
534
    }
535
536
    /**
537
     * Get bookings
538
     */
539 3
    public function getBookings(): Collection
540
    {
541 3
        return $this->bookings;
542
    }
543
544
    /**
545
     * Get active bookings (confirmed and non-terminated)
546
     *
547
     * @API\Exclude
548
     */
549 2
    public function getRunningBookings(): Collection
550
    {
551
        return $this->bookings->filter(function (Booking $booking) {
552 2
            return $booking->getStatus() === BookingStatusType::BOOKED && $booking->getEndDate() === null;
553 2
        });
554
    }
555
556
    /**
557
     * Notify the user that it has a new booking.
558
     * This should only be called by Booking::setResponsible()
559
     */
560 16
    public function bookingAdded(Booking $booking): void
561
    {
562 16
        $this->bookings->add($booking);
563 16
    }
564
565
    /**
566
     * Notify the user that it has a booking was removed.
567
     * This should only be called by Booking::setResponsible()
568
     */
569 4
    public function bookingRemoved(Booking $booking): void
570
    {
571 4
        $this->bookings->removeElement($booking);
572 4
    }
573
574 2
    public function getLicenses(): Collection
575
    {
576 2
        return $this->licenses;
577
    }
578
579 1
    public function getUserTags(): Collection
580
    {
581 1
        return $this->userTags;
582
    }
583
584
    /**
585
     * Notify the user that it has a new license.
586
     * This should only be called by License::addUser()
587
     */
588 1
    public function licenseAdded(License $license): void
589
    {
590 1
        $this->licenses->add($license);
591 1
    }
592
593
    /**
594
     * Notify the user that it a license was removed.
595
     * This should only be called by License::removeUser()
596
     */
597 1
    public function licenseRemoved(License $license): void
598
    {
599 1
        $this->licenses->removeElement($license);
600 1
    }
601
602
    /**
603
     * Notify the user that it has a new userTag.
604
     * This should only be called by UserTag::addUser()
605
     */
606 1
    public function userTagAdded(UserTag $userTag): void
607
    {
608 1
        $this->userTags->add($userTag);
609 1
    }
610
611
    /**
612
     * Notify the user that a userTag was removed.
613
     * This should only be called by UserTag::removeUser()
614
     */
615 1
    public function userTagRemoved(UserTag $userTag): void
616
    {
617 1
        $this->userTags->removeElement($userTag);
618 1
    }
619
620
    public function isTermsAgreement(): bool
621
    {
622
        return $this->termsAgreement;
623
    }
624
625 1
    public function setTermsAgreement(bool $termsAgreement): void
626
    {
627 1
        $this->termsAgreement = $termsAgreement;
628 1
    }
629
630
    public function hasInsurance(): bool
631
    {
632
        return $this->hasInsurance;
633
    }
634
635 1
    public function setHasInsurance(bool $hasInsurance): void
636
    {
637 1
        $this->hasInsurance = $hasInsurance;
638 1
    }
639
640
    public function getWelcomeSessionDate(): ?Chronos
641
    {
642
        return $this->welcomeSessionDate;
643
    }
644
645
    public function setWelcomeSessionDate(?Chronos $welcomeSessionDate): void
646
    {
647
        $this->welcomeSessionDate = $welcomeSessionDate;
648
    }
649
650
    public function getResignDate(): ?Chronos
651
    {
652
        return $this->resignDate;
653
    }
654
655 1
    public function setResignDate(?Chronos $resignDate): void
656
    {
657 1
        $this->resignDate = $resignDate;
658 1
    }
659
660
    public function getReceivesNewsletter(): bool
661
    {
662
        return $this->receivesNewsletter;
663
    }
664
665
    public function setReceivesNewsletter(bool $receivesNewsletter): void
666
    {
667
        $this->receivesNewsletter = $receivesNewsletter;
668
    }
669
670
    /**
671
     * Get the sex
672
     *
673
     * @API\Field(type="Sex")
674
     */
675
    public function getSex(): int
676
    {
677
        return $this->sex;
678
    }
679
680
    /**
681
     * Set the sex
682
     *
683
     * @API\Input(type="Sex")
684
     */
685
    public function setSex(int $sex): void
686
    {
687
        $this->sex = $sex;
688
    }
689
690
    /**
691
     * Get the Swiss Sailing licence number
692
     */
693
    public function getSwissSailing(): string
694
    {
695
        return $this->swissSailing;
696
    }
697
698
    public function setSwissSailing(string $swissSailing): void
699
    {
700
        $this->swissSailing = $swissSailing;
701
    }
702
703
    /**
704
     * Get the Swiss Sailing licence type
705
     *
706
     * @API\Field(type="?SwissSailingType")
707
     */
708
    public function getSwissSailingType(): ?string
709
    {
710
        return $this->swissSailingType;
711
    }
712
713
    /**
714
     * Set the Swiss Sailing licence type
715
     *
716
     * @API\Input(type="?SwissSailingType")
717
     */
718
    public function setSwissSailingType(?string $swissSailingType): void
719
    {
720
        $this->swissSailingType = $swissSailingType;
721
    }
722
723
    /**
724
     * Get the Swiss Windsurf licence type
725
     *
726
     * @API\Field(type="?SwissWindsurfType")
727
     */
728
    public function getSwissWindsurfType(): ?string
729
    {
730
        return $this->swissWindsurfType;
731
    }
732
733
    /**
734
     * Set the Swiss Windsurf licence type
735
     *
736
     * @API\Input(type="?SwissWindsurfType")
737
     */
738
    public function setSwissWindsurfType(?string $swissWindsurfType): void
739
    {
740
        $this->swissWindsurfType = $swissWindsurfType;
741
    }
742
743
    /**
744
     * Get the first login date
745
     */
746
    public function getFirstLogin(): ?Chronos
747
    {
748
        /** @var LogRepository $logRepository */
749
        $logRepository = _em()->getRepository(Log::class);
750
751
        return $logRepository->getLoginDate($this, true);
752
    }
753
754
    /**
755
     * Get the last login date
756
     */
757
    public function getLastLogin(): ?Chronos
758
    {
759
        /** @var LogRepository $logRepository */
760
        $logRepository = _em()->getRepository(Log::class);
761
762
        return $logRepository->getLoginDate($this, false);
763
    }
764
765
    /**
766
     * @API\Field(type="Relationship")
767
     */
768 1
    public function getFamilyRelationship(): string
769
    {
770 1
        return $this->familyRelationship;
771
    }
772
773
    /**
774
     * @API\Input(type="Relationship")
775
     */
776 1
    public function setFamilyRelationship(string $familyRelationship): void
777
    {
778 1
        $this->familyRelationship = $familyRelationship;
779 1
    }
780
781
    /**
782
     * @API\Field(type="BillingType")
783
     */
784
    public function getBillingType(): string
785
    {
786
        return $this->billingType;
787
    }
788
789
    /**
790
     * @API\Input(type="BillingType")
791
     */
792
    public function setBillingType(string $billingType): void
793
    {
794
        $this->billingType = $billingType;
795
    }
796
797
    /**
798
     * Get the user transaction account
799
     */
800 27
    public function getAccount(): ?Account
801
    {
802 27
        if ($this->getOwner() && $this->getOwner() !== $this) {
803 7
            return $this->getOwner()->getAccount();
804
        }
805
806 27
        return $this->accounts->count() ? $this->accounts->first() : null;
807
    }
808
809
    /**
810
     * Notify the user that it has a new account
811
     * This should only be called by Account::setOwner()
812
     */
813 13
    public function accountAdded(Account $account): void
814
    {
815 13
        $this->accounts->clear();
816 13
        $this->accounts->add($account);
817 13
    }
818
819
    /**
820
     * Notify the user that a account was removed
821
     * This should only be called by Account::setOwner()
822
     */
823 1
    public function accountRemoved(): void
824
    {
825 1
        $this->accounts->clear();
826 1
    }
827
828
    /**
829
     * Get messages sent to the user
830
     */
831 1
    public function getMessages(): Collection
832
    {
833 1
        return $this->messages;
834
    }
835
836
    /**
837
     * Notify the user that it has a new message
838
     * This should only be called by Message::setRecipient()
839
     */
840 8
    public function messageAdded(Message $message): void
841
    {
842 8
        $this->messages->add($message);
843 8
    }
844
845
    /**
846
     * Notify the user that a message was removed
847
     * This should only be called by Message::setRecipient()
848
     */
849 1
    public function messageRemoved(Message $message): void
850
    {
851 1
        $this->messages->removeElement($message);
852 1
    }
853
854
    /**
855
     * Check if the user can *really* open a door
856
     * This also takes into account the user status and role
857
     *
858
     * @API\Field(args={@API\Argument(name="door", type="?Application\Api\Enum\DoorType")})
859
     *
860
     * @param null|string $door a particular door, or null for any
861
     */
862 6
    public function getCanOpenDoor(?string $door = null): bool
863
    {
864 6
        $allowedStatus = [self::STATUS_ACTIVE];
865 6
        $allowedRoles = [self::ROLE_INDIVIDUAL, self::ROLE_MEMBER, self::ROLE_TRAINER, self::ROLE_RESPONSIBLE, self::ROLE_ADMINISTRATOR];
866
867 6
        if ($door && !$this->$door) {
868 3
            return false;
869
        }
870
871 6
        if (!in_array($this->status, $allowedStatus, true) || !in_array($this->role, $allowedRoles, true)) {
872 2
            return false;
873
        }
874
875 4
        return true;
876
    }
877
878
    /**
879
     * Override parent to prevents users created from administration to be family of the administrator
880
     *
881
     * The owner must be explicitly set for all users.
882
     */
883 3
    protected function getOwnerForCreation(): ?self
884
    {
885 3
        return null;
886
    }
887
}
888