Passed
Push — master ( f7c150...1627a8 )
by Sam
07:43
created

User::getReceivesNewsletter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
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\Api\Exception;
8
use Application\DBAL\Types\BillingTypeType;
9
use Application\DBAL\Types\RelationshipType;
10
use Application\ORM\Query\Filter\AclFilter;
11
use Application\Traits\HasAddress;
12
use Application\Traits\HasDoorAccess;
13
use Application\Traits\HasIban;
14
use Application\Traits\HasInternalRemarks;
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 GraphQL\Doctrine\Annotation as API;
22
23
/**
24
 * User
25
 *
26
 * @ORM\Entity(repositoryClass="Application\Repository\UserRepository")
27
 * @ORM\AssociationOverrides({
28
 *     @ORM\AssociationOverride(name="owner", inversedBy="users")
29
 * })
30
 * @API\Sorting({
31
 *     "Application\Api\Input\Sorting\Age"
32
 * })
33
 */
34
class User extends AbstractModel
35
{
36
    const ROLE_ANONYMOUS = 'anonymous';
37
    const ROLE_BOOKING_ONLY = 'booking_only';
38
    const ROLE_INDIVIDUAL = 'individual';
39
    const ROLE_MEMBER = 'member';
40
    const ROLE_RESPONSIBLE = 'responsible';
41
    const ROLE_ADMINISTRATOR = 'administrator';
42
43
    const STATUS_INACTIVE = 'inactive';
44
    const STATUS_NEW = 'new';
45
    const STATUS_ACTIVE = 'active';
46
    const STATUS_ARCHIVED = 'archived';
47
48
    use HasDoorAccess;
49
    use HasRemarks;
50
    use HasInternalRemarks;
51
    use HasAddress;
52
    use HasIban;
53
54
    /**
55
     * @var User
56
     */
57
    private static $currentUser;
58
59
    /**
60
     * Set currently logged in user
61
     * WARNING: this method should only be called from \Application\Authentication\AuthenticationListener
62
     *
63
     * @param \Application\Model\User $user
64
     */
65 164
    public static function setCurrent(?self $user): void
66
    {
67 164
        self::$currentUser = $user;
68
69
        // Initalize ACL filter with current user if a logged in one exists
70 164
        _em()->getFilters()->getFilter(AclFilter::class)->setUser($user);
71 164
    }
72
73
    /**
74
     * Returns currently logged user or null
75
     *
76
     * @return null|self
77
     */
78 67
    public static function getCurrent(): ?self
79
    {
80 67
        return self::$currentUser;
81
    }
82
83
    /**
84
     * @var null|string
85
     *
86
     * @ORM\Column(type="string", length=50, nullable=true, unique=true)
87
     */
88
    private $login;
89
90
    /**
91
     * @var string
92
     * @ORM\Column(type="string", length=191)
93
     */
94
    private $firstName = '';
95
96
    /**
97
     * @var string
98
     * @ORM\Column(type="string", length=191)
99
     */
100
    private $lastName = '';
101
102
    /**
103
     * @var string
104
     *
105
     * @ORM\Column(type="string", length=255)
106
     */
107
    private $password = '';
108
109
    /**
110
     * @var null|string
111
     * @ORM\Column(type="string", length=191, nullable=true, unique=true)
112
     */
113
    private $email;
114
115
    /**
116
     * @var string
117
     * @ORM\Column(type="UserRole", options={"default" = User::ROLE_INDIVIDUAL})
118
     */
119
    private $role = self::ROLE_INDIVIDUAL;
120
121
    /**
122
     * @var string
123
     * @ORM\Column(type="UserStatus", options={"default" = User::STATUS_NEW})
124
     */
125
    private $status = self::STATUS_NEW;
126
127
    /**
128
     * @var null|Chronos
129
     * @ORM\Column(type="datetime", nullable=true)
130
     */
131
    private $lastLogin;
132
133
    /**
134
     * @var null|Chronos
135
     * @ORM\Column(type="datetime", nullable=true)
136
     */
137
    private $welcomeSessionDate;
138
139
    /**
140
     * @var int sex
141
     * @ORM\Column(type="smallint", options={"default" = 0}))
142
     */
143
    private $sex = 0;
144
145
    /**
146
     * @var string
147
     * @ORM\Column(type="string", length=25, options={"default" = ""})
148
     */
149
    private $phone = '';
150
151
    /**
152
     * @var string
153
     * @ORM\Column(type="string", length=25, options={"default" = ""})
154
     */
155
    private $mobilePhone = '';
156
157
    /**
158
     * @var string
159
     * @ORM\Column(type="string", length=25, options={"default" = ""})
160
     */
161
    private $swissSailing = '';
162
163
    /**
164
     * @var string
165
     * @ORM\Column(type="SwissSailingType", nullable=true)
166
     */
167
    private $swissSailingType;
168
169
    /**
170
     * @var string
171
     * @ORM\Column(type="SwissWindsurfType", nullable=true)
172
     */
173
    private $swissWindsurfType;
174
175
    /**
176
     * @var null|Date
177
     * @ORM\Column(type="date", nullable=true)
178
     */
179
    private $birthday;
180
181
    /**
182
     * @var bool
183
     * @ORM\Column(type="boolean", options={"default" = 0})
184
     */
185
    private $termsAgreement = false;
186
187
    /**
188
     * @var bool
189
     * @ORM\Column(type="boolean", options={"default" = 0})
190
     */
191
    private $hasInsurance = false;
192
193
    /**
194
     * @var bool
195
     * @ORM\Column(type="boolean", options={"default" = 0})
196
     */
197
    private $receivesNewsletter = false;
198
199
    /**
200
     * @var string
201
     * @ORM\Column(type="Relationship", options={"default" = RelationshipType::HOUSEHOLDER})
202
     */
203
    private $familyRelationship = RelationshipType::HOUSEHOLDER;
204
205
    /**
206
     * @var string
207
     * @ORM\Column(type="BillingType", options={"default" = BillingTypeType::ELECTRONIC})
208
     */
209
    private $billingType = BillingTypeType::ELECTRONIC;
210
211
    /**
212
     * @var null|string
213
     * @ORM\Column(type="string", length=32, nullable=true, unique=true)
214
     */
215
    private $token;
216
217
    /**
218
     * @var null|Chronos
219
     *
220
     * @ORM\Column(type="datetime", nullable=true)
221
     */
222
    private $tokenCreationDate;
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 40
    public function __construct(string $role = self::ROLE_INDIVIDUAL)
269
    {
270 40
        $this->role = $role;
271 40
        $this->bookings = new ArrayCollection();
272 40
        $this->accounts = new ArrayCollection();
273 40
        $this->licenses = new ArrayCollection();
274 40
        $this->userTags = new ArrayCollection();
275 40
        $this->messages = new ArrayCollection();
276 40
        $this->users = new ArrayCollection();
277 40
    }
278
279
    /**
280
     * Set login (eg: johndoe)
281
     *
282
     * @API\Input(type="Login")
283
     *
284
     * @param string $login
285
     */
286 4
    public function setLogin(string $login): void
287
    {
288 4
        $this->login = $login;
289 4
    }
290
291
    /**
292
     * Get login (eg: johndoe)
293
     *
294
     * @API\Field(type="?Login")
295
     *
296
     * @return null|string
297
     */
298 11
    public function getLogin(): ?string
299
    {
300 11
        return $this->login;
301
    }
302
303
    /**
304
     * Hash and change the user password
305
     *
306
     * @param string $password
307
     */
308 6
    public function setPassword(string $password): void
309
    {
310
        // Ignore empty password that could be sent "by mistake" by the client
311
        // when agreeing to terms
312 6
        if ($password === '') {
313 1
            return;
314
        }
315
316 6
        $this->revokeToken();
317
318 6
        $this->password = password_hash($password, PASSWORD_DEFAULT);
319 6
    }
320
321
    /**
322
     * Returns the hashed password
323
     *
324
     * @API\Exclude
325
     *
326
     * @return string
327
     */
328 3
    public function getPassword(): string
329
    {
330 3
        return $this->password;
331
    }
332
333
    /**
334
     * Set first name
335
     *
336
     * @param string $firstName
337
     */
338 5
    public function setFirstName($firstName): void
339
    {
340 5
        $this->firstName = $firstName;
341 5
    }
342
343
    /**
344
     * Get first name
345
     *
346
     * @return string
347
     */
348 12
    public function getFirstName(): string
349
    {
350 12
        return (string) $this->firstName;
351
    }
352
353
    /**
354
     * Set last name
355
     *
356
     * @param string $lastName
357
     */
358 5
    public function setLastName($lastName): void
359
    {
360 5
        $this->lastName = $lastName;
361 5
    }
362
363
    /**
364
     * Get last name
365
     *
366
     * @return string
367
     */
368 6
    public function getLastName(): string
369
    {
370 6
        return (string) $this->lastName;
371
    }
372
373
    /**
374
     * Get full name
375
     *
376
     * @return string
377
     */
378 6
    public function getName(): string
379
    {
380 6
        return implode(' ', [$this->getFirstName(), $this->getLastName()]);
381
    }
382
383
    /**
384
     * Set email
385
     *
386
     * @API\Input(type="?Email")
387
     *
388
     * @param string $email
389
     */
390 5
    public function setEmail(string $email): void
391
    {
392 5
        $this->email = $email;
393 5
    }
394
395
    /**
396
     * Get email
397
     *
398
     * @API\Field(type="?Email")
399
     *
400
     * @return null|string
401
     */
402 14
    public function getEmail(): ?string
403
    {
404 14
        return $this->email;
405
    }
406
407
    /**
408
     * Returns whether the user is administrator and thus have can do anything.
409
     *
410
     * @API\Field(type="Application\Api\Enum\UserRoleType")
411
     */
412 78
    public function getRole(): string
413
    {
414 78
        return $this->role;
415
    }
416
417
    /**
418
     * Sets the user role
419
     *
420
     * The current user is allowed to promote another user up to the same role as himself. So
421
     * a Responsible can promote a Member to Responsible. Or an Admin can promote a Individual to Admin.
422
     *
423
     * But the current user is **not** allowed to demote a user who has a higher role than himself.
424
     * That means that a Responsible cannot demote an Admin to Individual.
425
     *
426
     * @param string $role
427
     */
428 7
    public function setRole(string $role): void
429
    {
430 7
        if ($role === $this->role) {
431 2
            return;
432
        }
433
434 5
        $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
435
        $orderedRoles = [
436 5
            self::ROLE_ANONYMOUS,
437 5
            self::ROLE_INDIVIDUAL,
438 5
            self::ROLE_MEMBER,
439 5
            self::ROLE_BOOKING_ONLY,
440 5
            self::ROLE_RESPONSIBLE,
441 5
            self::ROLE_ADMINISTRATOR,
442
        ];
443
444 5
        $newFound = false;
445 5
        $oldFound = false;
446 5
        foreach ($orderedRoles as $r) {
447 5
            if ($r === $this->role) {
448 3
                $oldFound = true;
449
            }
450 5
            if ($r === $role) {
451 2
                $newFound = true;
452
            }
453
454 5
            if ($r === $currentRole) {
455 5
                break;
456
            }
457
        }
458
459 5
        if (!$newFound || !$oldFound) {
460 3
            throw new Exception($currentRole . ' is not allowed to change role from ' . $this->role . ' to ' . $role);
461
        }
462
463 2
        $this->role = $role;
464 2
    }
465
466 7
    public function setOwner(self $owner = null): void
467
    {
468 7
        if ($owner && $owner !== $this) {
469 4
            if ($owner->getOwner() && $owner !== $owner->getOwner()) {
470 1
                throw new Exception('This user cannot be owned by a user who is himself owned by somebody else');
471
            }
472
473 4
            if ($this->users->count()) {
474 1
                throw new Exception('This user owns other users, so he cannot himself be owned by somebody else');
475
            }
476
        }
477
478 7
        if ($this->getOwner()) {
479 1
            $this->getOwner()->getEmail(); // Trigger lazy loading
480 1
            $this->getOwner()->users->removeElement($this);
481
        }
482
483 7
        parent::setOwner($owner);
484
485 7
        if ($this->getOwner()) {
486 5
            $this->getOwner()->getEmail(); // Trigger lazy loading
487 5
            $this->getOwner()->users->add($this);
488 5
            $this->setStatus($this->getOwner()->getStatus());
489
        }
490 7
    }
491
492
    /**
493
     * @API\Field(type="Application\Api\Enum\UserStatusType")
494
     *
495
     * @return string
496
     */
497 7
    public function getStatus(): string
498
    {
499 7
        return $this->status;
500
    }
501
502
    /**
503
     * @API\Input(type="Application\Api\Enum\UserStatusType")
504
     *
505
     * @param string $status
506
     */
507 14
    public function setStatus(string $status): void
508
    {
509 14
        $this->status = $status;
510 14
        $this->revokeToken();
511
512 14
        foreach ($this->users as $user) {
513 4
            if ($user !== $this) {
514 1
                $user->setStatus($status);
515
            }
516
        }
517 14
    }
518
519 1
    public function activate(): void
520
    {
521 1
        $this->role = self::ROLE_MEMBER; // Bypass security
522 1
        $this->setStatus(self::STATUS_ACTIVE);
523 1
    }
524
525
    /**
526
     * @return string
527
     */
528
    public function getPhone(): string
529
    {
530
        return $this->phone;
531
    }
532
533
    /**
534
     * @param string $phone
535
     */
536
    public function setPhone(string $phone): void
537
    {
538
        $this->phone = $phone;
539
    }
540
541
    /**
542
     * @return string
543
     */
544
    public function getMobilePhone(): string
545
    {
546
        return $this->mobilePhone;
547
    }
548
549
    /**
550
     * @param string $mobilePhone
551
     */
552
    public function setMobilePhone(string $mobilePhone): void
553
    {
554
        $this->mobilePhone = $mobilePhone;
555
    }
556
557
    /**
558
     * @return null|Date
559
     */
560
    public function getBirthday(): ?Date
561
    {
562
        return $this->birthday;
563
    }
564
565
    /**
566
     * @param null|Date $birthday
567
     */
568
    public function setBirthday(?Date $birthday): void
569
    {
570
        $this->birthday = $birthday;
571
    }
572
573
    /**
574
     * return null|int
575
     */
576
    public function getAge(): ?int
577
    {
578
        if ($this->birthday) {
579
            return (new Date())->diffInYears($this->birthday);
580
        }
581
582
        return null;
583
    }
584
585
    /**
586
     * Get bookings
587
     *
588
     * @return Collection
589
     */
590 4
    public function getBookings(): Collection
591
    {
592 4
        return $this->bookings;
593
    }
594
595
    /**
596
     * Notify the user that it has a new booking.
597
     * This should only be called by Booking::setResponsible()
598
     *
599
     * @param Booking $booking
600
     */
601 8
    public function bookingAdded(Booking $booking): void
602
    {
603 8
        $this->bookings->add($booking);
604 8
    }
605
606
    /**
607
     * Notify the user that it has a booking was removed.
608
     * This should only be called by Booking::setResponsible()
609
     *
610
     * @param Booking $booking
611
     */
612 4
    public function bookingRemoved(Booking $booking): void
613
    {
614 4
        $this->bookings->removeElement($booking);
615 4
    }
616
617
    /**
618
     * @return Collection
619
     */
620 1
    public function getLicenses(): Collection
621
    {
622 1
        return $this->licenses;
623
    }
624
625
    /**
626
     * @return Collection
627
     */
628 1
    public function getUserTags(): Collection
629
    {
630 1
        return $this->userTags;
631
    }
632
633
    /**
634
     * Notify the user that it has a new license.
635
     * This should only be called by License::addUser()
636
     *
637
     * @param License $license
638
     */
639 1
    public function licenseAdded(License $license): void
640
    {
641 1
        $this->licenses->add($license);
642 1
    }
643
644
    /**
645
     * Notify the user that it a license was removed.
646
     * This should only be called by License::removeUser()
647
     *
648
     * @param License $license
649
     */
650 1
    public function licenseRemoved(License $license): void
651
    {
652 1
        $this->licenses->removeElement($license);
653 1
    }
654
655
    /**
656
     * Notify the user that it has a new userTag.
657
     * This should only be called by UserTag::addUser()
658
     *
659
     * @param UserTag $userTag
660
     */
661 1
    public function userTagAdded(UserTag $userTag): void
662
    {
663 1
        $this->userTags->add($userTag);
664 1
    }
665
666
    /**
667
     * Notify the user that a userTag was removed.
668
     * This should only be called by UserTag::removeUser()
669
     *
670
     * @param UserTag $userTag
671
     */
672 1
    public function userTagRemoved(UserTag $userTag): void
673
    {
674 1
        $this->userTags->removeElement($userTag);
675 1
    }
676
677
    /**
678
     * @return bool
679
     */
680
    public function isTermsAgreement(): bool
681
    {
682
        return $this->termsAgreement;
683
    }
684
685
    /**
686
     * @param bool $termsAgreement
687
     */
688 1
    public function setTermsAgreement(bool $termsAgreement): void
689
    {
690 1
        $this->termsAgreement = $termsAgreement;
691 1
    }
692
693
    /**
694
     * @return bool
695
     */
696
    public function hasInsurance(): bool
697
    {
698
        return $this->hasInsurance;
699
    }
700
701
    /**
702
     * @param bool $hasInsurance
703
     */
704 1
    public function setHasInsurance(bool $hasInsurance): void
705
    {
706 1
        $this->hasInsurance = $hasInsurance;
707 1
    }
708
709
    /**
710
     * @return null|Chronos
711
     */
712
    public function getWelcomeSessionDate(): ?Chronos
713
    {
714
        return $this->welcomeSessionDate;
715
    }
716
717
    /**
718
     * @param null|Chronos $welcomeSessionDate
719
     */
720
    public function setWelcomeSessionDate(?Chronos $welcomeSessionDate): void
721
    {
722
        $this->welcomeSessionDate = $welcomeSessionDate;
723
    }
724
725
    /**
726
     * @return bool
727
     */
728
    public function getReceivesNewsletter(): bool
729
    {
730
        return $this->receivesNewsletter;
731
    }
732
733
    /**
734
     * @param bool $receivesNewsletter
735
     */
736
    public function setReceivesNewsletter(bool $receivesNewsletter): void
737
    {
738
        $this->receivesNewsletter = $receivesNewsletter;
739
    }
740
741
    /**
742
     * Get the sex
743
     *
744
     * @API\Field(type="Sex")
745
     *
746
     * @return int
747
     */
748
    public function getSex(): int
749
    {
750
        return $this->sex;
751
    }
752
753
    /**
754
     * Set the sex
755
     *
756
     * @API\Input(type="Sex")
757
     *
758
     * @param int $sex
759
     */
760
    public function setSex(int $sex): void
761
    {
762
        $this->sex = $sex;
763
    }
764
765
    /**
766
     * Get the Swiss Sailing licence number
767
     *
768
     * @return string
769
     */
770
    public function getSwissSailing(): string
771
    {
772
        return $this->swissSailing;
773
    }
774
775
    /**
776
     * @param string $swissSailing
777
     */
778
    public function setSwissSailing(string $swissSailing): void
779
    {
780
        $this->swissSailing = $swissSailing;
781
    }
782
783
    /**
784
     * Get the Swiss Sailing licence type
785
     *
786
     * @API\Field(type="?SwissSailingType")
787
     *
788
     * @return null|string
789
     */
790
    public function getSwissSailingType(): ?string
791
    {
792
        return $this->swissSailingType;
793
    }
794
795
    /**
796
     * Set the Swiss Sailing licence type
797
     *
798
     * @API\Input(type="?SwissSailingType")
799
     *
800
     * @param null|string $swissSailingType
801
     */
802
    public function setSwissSailingType(?string $swissSailingType): void
803
    {
804
        $this->swissSailingType = $swissSailingType;
805
    }
806
807
    /**
808
     * Get the Swiss Windsurf licence type
809
     *
810
     * @API\Field(type="?SwissWindsurfType")
811
     *
812
     * @return null|string
813
     */
814
    public function getSwissWindsurfType(): ?string
815
    {
816
        return $this->swissWindsurfType;
817
    }
818
819
    /**
820
     * Set the Swiss Windsurf licence type
821
     *
822
     * @API\Input(type="?SwissWindsurfType")
823
     *
824
     * @param null|string $swissWindsurfType
825
     */
826
    public function setSwissWindsurfType(?string $swissWindsurfType): void
827
    {
828
        $this->swissWindsurfType = $swissWindsurfType;
829
    }
830
831
    /**
832
     * Get the last login
833
     *
834
     * @return null|Chronos
835
     */
836
    public function getLastLogin(): ?Chronos
837
    {
838
        return $this->lastLogin;
839
    }
840
841
    /**
842
     * @param null|Chronos $lastLogin
843
     */
844 3
    public function setLastLogin(?Chronos $lastLogin): void
845
    {
846 3
        $this->lastLogin = $lastLogin;
847 3
        $this->revokeToken();
848 3
    }
849
850
    /**
851
     * @API\Field(type="Relationship")
852
     *
853
     * @return string
854
     */
855 1
    public function getFamilyRelationship(): string
856
    {
857 1
        return $this->familyRelationship;
858
    }
859
860
    /**
861
     * @API\Input(type="Relationship")
862
     *
863
     * @param string $familyRelationship
864
     */
865 1
    public function setFamilyRelationship(string $familyRelationship): void
866
    {
867 1
        $this->familyRelationship = $familyRelationship;
868 1
    }
869
870
    /**
871
     * @API\Field(type="BillingType")
872
     *
873
     * @return string
874
     */
875
    public function getBillingType(): string
876
    {
877
        return $this->billingType;
878
    }
879
880
    /**
881
     * @API\Input(type="BillingType")
882
     *
883
     * @param string $billingType
884
     */
885
    public function setBillingType(string $billingType): void
886
    {
887
        $this->billingType = $billingType;
888
    }
889
890
    /**
891
     * Get the user transaction account
892
     *
893
     * @return null|Account
894
     */
895 6
    public function getAccount(): ?Account
896
    {
897 6
        return $this->accounts->count() ? $this->accounts->first() : null;
898
    }
899
900
    /**
901
     * Notify the user that it has a new account
902
     * This should only be called by Account::setOwner()
903
     *
904
     * @param Account $account
905
     */
906 7
    public function accountAdded(Account $account): void
907
    {
908 7
        $this->accounts->clear();
909 7
        $this->accounts->add($account);
910 7
    }
911
912
    /**
913
     * Notify the user that a account was removed
914
     * This should only be called by Account::setOwner()
915
     */
916 4
    public function accountRemoved(): void
917
    {
918 4
        $this->accounts->clear();
919 4
    }
920
921
    /**
922
     * Get messages sent to the user
923
     *
924
     * @return Collection
925
     */
926 1
    public function getMessages(): Collection
927
    {
928 1
        return $this->messages;
929
    }
930
931
    /**
932
     * Notify the user that it has a new message
933
     * This should only be called by Message::setRecipient()
934
     *
935
     * @param Message $message
936
     */
937 8
    public function messageAdded(Message $message): void
938
    {
939 8
        $this->messages->add($message);
940 8
    }
941
942
    /**
943
     * Notify the user that a message was removed
944
     * This should only be called by Message::setRecipient()
945
     *
946
     * @param Message $message
947
     */
948 1
    public function messageRemoved(Message $message): void
949
    {
950 1
        $this->messages->removeElement($message);
951 1
    }
952
953
    /**
954
     * Generate a new random token to reset password
955
     */
956 4
    public function createToken(): string
957
    {
958 4
        $this->token = bin2hex(random_bytes(16));
959 4
        $this->tokenCreationDate = new Chronos();
960
961 4
        return $this->token;
962
    }
963
964
    /**
965
     * Destroy existing token
966
     */
967 18
    private function revokeToken(): void
968
    {
969 18
        $this->token = null;
970 18
        $this->tokenCreationDate = null;
971 18
    }
972
973
    /**
974
     * Check if token is valid.
975
     *
976
     * @API\Exclude
977
     *
978
     * @return bool
979
     */
980 3
    public function isTokenValid(): bool
981
    {
982 3
        if (!$this->tokenCreationDate) {
983 1
            return false;
984
        }
985
986 3
        $timeLimit = $this->tokenCreationDate->addMinutes(30);
987
988 3
        return $timeLimit->isFuture();
989
    }
990
991
    /**
992
     * Check if the user can *really* open a door
993
     * This also takes into account the user status and role
994
     *
995
     * @API\Field(args={@API\Argument(name="door", type="?Application\Api\Enum\DoorType")})
996
     *
997
     * @param null|string $door a particular door, or null for any
998
     *
999
     * @return bool
1000
     */
1001 6
    public function getCanOpenDoor(?string $door = null): bool
1002
    {
1003 6
        $allowedStatus = [self::STATUS_ACTIVE];
1004 6
        $allowedRoles = [self::ROLE_INDIVIDUAL, self::ROLE_MEMBER, self::ROLE_RESPONSIBLE, self::ROLE_ADMINISTRATOR];
1005
1006 6
        if ($door && !$this->$door) {
1007 3
            return false;
1008
        }
1009
1010 6
        if (!in_array($this->status, $allowedStatus, true) || !in_array($this->role, $allowedRoles, true)) {
1011 2
            return false;
1012
        }
1013
1014 4
        return true;
1015
    }
1016
}
1017