Completed
Push — master ( ab511a...a15fad )
by Sylvain
15:21
created

User::getAge()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
ccs 1
cts 1
cp 1
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 163
     *
63
     * @param \Application\Model\User $user
64 163
     */
65
    public static function setCurrent(?self $user): void
66
    {
67 163
        self::$currentUser = $user;
68 163
69
        // Initalize ACL filter with current user if a logged in one exists
70
        _em()->getFilters()->getFilter(AclFilter::class)->setUser($user);
71
    }
72
73
    /**
74
     * Returns currently logged user or null
75 67
     *
76
     * @return null|self
77 67
     */
78
    public static function getCurrent(): ?self
79
    {
80
        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 39
     *
266
     * @param string $role role for new user
267 39
     */
268 39
    public function __construct(string $role = self::ROLE_INDIVIDUAL)
269 39
    {
270 39
        $this->role = $role;
271 39
        $this->bookings = new ArrayCollection();
272 39
        $this->accounts = new ArrayCollection();
273 39
        $this->licenses = new ArrayCollection();
274 39
        $this->userTags = new ArrayCollection();
275
        $this->messages = new ArrayCollection();
276
        $this->users = new ArrayCollection();
277
    }
278
279
    /**
280
     * Set login (eg: johndoe)
281
     *
282
     * @API\Input(type="Login")
283 4
     *
284
     * @param string $login
285 4
     */
286 4
    public function setLogin(string $login): void
287
    {
288
        $this->login = $login;
289
    }
290
291
    /**
292
     * Get login (eg: johndoe)
293
     *
294
     * @API\Field(type="?Login")
295 11
     *
296
     * @return null|string
297 11
     */
298
    public function getLogin(): ?string
299
    {
300
        return $this->login;
301
    }
302
303
    /**
304
     * Hash and change the user password
305 6
     *
306
     * @param string $password
307
     */
308
    public function setPassword(string $password): void
309 6
    {
310 1
        // Ignore empty password that could be sent "by mistake" by the client
311
        // when agreeing to terms
312
        if ($password === '') {
313 6
            return;
314
        }
315 6
316 6
        $this->revokeToken();
317
318
        $this->password = password_hash($password, PASSWORD_DEFAULT);
319
    }
320
321
    /**
322
     * Returns the hashed password
323
     *
324
     * @API\Exclude
325 3
     *
326
     * @return string
327 3
     */
328
    public function getPassword(): string
329
    {
330
        return $this->password;
331
    }
332
333
    /**
334
     * Set first name
335 5
     *
336
     * @param string $firstName
337 5
     */
338 5
    public function setFirstName($firstName): void
339
    {
340
        $this->firstName = $firstName;
341
    }
342
343
    /**
344
     * Get first name
345 12
     *
346
     * @return string
347 12
     */
348
    public function getFirstName(): string
349
    {
350
        return (string) $this->firstName;
351
    }
352
353
    /**
354
     * Set last name
355 5
     *
356
     * @param string $lastName
357 5
     */
358 5
    public function setLastName($lastName): void
359
    {
360
        $this->lastName = $lastName;
361
    }
362
363
    /**
364
     * Get last name
365 6
     *
366
     * @return string
367 6
     */
368
    public function getLastName(): string
369
    {
370
        return (string) $this->lastName;
371
    }
372
373
    /**
374
     * Get full name
375 6
     *
376
     * @return string
377 6
     */
378
    public function getName(): string
379
    {
380
        return implode(' ', [$this->getFirstName(), $this->getLastName()]);
381
    }
382
383
    /**
384
     * Set email
385
     *
386
     * @API\Input(type="?Email")
387 5
     *
388
     * @param string $email
389 5
     */
390 5
    public function setEmail(string $email): void
391
    {
392
        $this->email = $email;
393
    }
394
395
    /**
396
     * Get email
397
     *
398
     * @API\Field(type="?Email")
399 14
     *
400
     * @return null|string
401 14
     */
402
    public function getEmail(): ?string
403
    {
404
        return $this->email;
405
    }
406
407
    /**
408
     * Returns whether the user is administrator and thus have can do anything.
409 77
     *
410
     * @API\Field(type="Application\Api\Enum\UserRoleType")
411 77
     */
412
    public function getRole(): string
413
    {
414
        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 7
     *
426
     * @param string $role
427 7
     */
428 2
    public function setRole(string $role): void
429
    {
430
        if ($role === $this->role) {
431 5
            return;
432
        }
433 5
434 5
        $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
435 5
        $orderedRoles = [
436 5
            self::ROLE_ANONYMOUS,
437 5
            self::ROLE_INDIVIDUAL,
438 5
            self::ROLE_MEMBER,
439
            self::ROLE_BOOKING_ONLY,
440
            self::ROLE_RESPONSIBLE,
441 5
            self::ROLE_ADMINISTRATOR,
442 5
        ];
443 5
444 5
        $newFound = false;
445 3
        $oldFound = false;
446
        foreach ($orderedRoles as $r) {
447 5
            if ($r === $this->role) {
448 2
                $oldFound = true;
449
            }
450
            if ($r === $role) {
451 5
                $newFound = true;
452 5
            }
453
454
            if ($r === $currentRole) {
455
                break;
456 5
            }
457 3
        }
458
459
        if (!$newFound || !$oldFound) {
460 2
            throw new Exception($currentRole . ' is not allowed to change role from ' . $this->role . ' to ' . $role);
461 2
        }
462
463 7
        $this->role = $role;
464
    }
465 7
466 4
    public function setOwner(self $owner = null): void
467 1
    {
468
        if ($owner && $owner !== $this) {
469
            if ($owner->getOwner() && $owner !== $owner->getOwner()) {
470 4
                throw new Exception('This user cannot be owned by a user who is himself owned by somebody else');
471 1
            }
472
473
            if ($this->users->count()) {
474
                throw new Exception('This user owns other users, so he cannot himself be owned by somebody else');
475 7
            }
476 1
        }
477 1
478
        if ($this->getOwner()) {
479
            $this->getOwner()->getEmail(); // Trigger lazy loading
480 7
            $this->getOwner()->users->removeElement($this);
481
        }
482 7
483 5
        parent::setOwner($owner);
484 5
485 5
        if ($this->getOwner()) {
486
            $this->getOwner()->getEmail(); // Trigger lazy loading
487 7
            $this->getOwner()->users->add($this);
488
            $this->setStatus($this->getOwner()->getStatus());
489
        }
490
    }
491
492
    /**
493
     * @API\Field(type="Application\Api\Enum\UserStatusType")
494 7
     *
495
     * @return string
496 7
     */
497
    public function getStatus(): string
498
    {
499
        return $this->status;
500
    }
501
502
    /**
503
     * @API\Input(type="Application\Api\Enum\UserStatusType")
504 14
     *
505
     * @param string $status
506 14
     */
507 14
    public function setStatus(string $status): void
508
    {
509 14
        $this->status = $status;
510 4
        $this->revokeToken();
511 1
512
        foreach ($this->users as $user) {
513
            if ($user !== $this) {
514 14
                $user->setStatus($status);
515
            }
516 1
        }
517
    }
518 1
519 1
    public function activate(): void
520 1
    {
521
        $this->role = self::ROLE_MEMBER; // Bypass security
522
        $this->setStatus(self::STATUS_ACTIVE);
523
    }
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 4
     */
576
    public function getAge(): ?int
577 4
    {
578
        if ($this->birthday) {
579
            return (new Date())->diffInYears($this->birthday);
580
        }
581
582
        return null;
583
    }
584
585
    /**
586 8
     * Get bookings
587
     *
588 8
     * @return Collection
589 8
     */
590
    public function getBookings(): Collection
591
    {
592
        return $this->bookings;
593
    }
594
595
    /**
596
     * Notify the user that it has a new booking.
597 4
     * This should only be called by Booking::setResponsible()
598
     *
599 4
     * @param Booking $booking
600 4
     */
601
    public function bookingAdded(Booking $booking): void
602
    {
603
        $this->bookings->add($booking);
604
    }
605 1
606
    /**
607 1
     * 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
    public function bookingRemoved(Booking $booking): void
613 1
    {
614
        $this->bookings->removeElement($booking);
615 1
    }
616
617
    /**
618
     * @return Collection
619
     */
620
    public function getLicenses(): Collection
621
    {
622
        return $this->licenses;
623
    }
624 1
625
    /**
626 1
     * @return Collection
627 1
     */
628
    public function getUserTags(): Collection
629
    {
630
        return $this->userTags;
631
    }
632
633
    /**
634
     * Notify the user that it has a new license.
635 1
     * This should only be called by License::addUser()
636
     *
637 1
     * @param License $license
638 1
     */
639
    public function licenseAdded(License $license): void
640
    {
641
        $this->licenses->add($license);
642
    }
643
644
    /**
645
     * Notify the user that it a license was removed.
646 1
     * This should only be called by License::removeUser()
647
     *
648 1
     * @param License $license
649 1
     */
650
    public function licenseRemoved(License $license): void
651
    {
652
        $this->licenses->removeElement($license);
653
    }
654
655
    /**
656
     * Notify the user that it has a new userTag.
657 1
     * This should only be called by UserTag::addUser()
658
     *
659 1
     * @param UserTag $userTag
660 1
     */
661
    public function userTagAdded(UserTag $userTag): void
662
    {
663
        $this->userTags->add($userTag);
664
    }
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
    public function userTagRemoved(UserTag $userTag): void
673 1
    {
674
        $this->userTags->removeElement($userTag);
675 1
    }
676 1
677
    /**
678
     * @return bool
679
     */
680
    public function isTermsAgreement(): bool
681
    {
682
        return $this->termsAgreement;
683
    }
684
685
    /**
686
     * @param bool $termsAgreement
687
     */
688
    public function setTermsAgreement(bool $termsAgreement): void
689 1
    {
690
        $this->termsAgreement = $termsAgreement;
691 1
    }
692 1
693
    /**
694
     * @return bool
695
     */
696
    public function hasInsurance(): bool
697
    {
698
        return $this->hasInsurance;
699
    }
700
701
    /**
702
     * @param bool $hasInsurance
703
     */
704
    public function setHasInsurance(bool $hasInsurance): void
705
    {
706
        $this->hasInsurance = $hasInsurance;
707
    }
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 isReceivesNewsletter(): 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 3
    }
830
831 3
    /**
832 3
     * Get the last login
833 3
     *
834
     * @return null|Chronos
835
     */
836
    public function getLastLogin(): ?Chronos
837
    {
838
        return $this->lastLogin;
839
    }
840 1
841
    /**
842 1
     * @param null|Chronos $lastLogin
843
     */
844
    public function setLastLogin(?Chronos $lastLogin): void
845
    {
846
        $this->lastLogin = $lastLogin;
847
        $this->revokeToken();
848
    }
849
850 1
    /**
851
     * @API\Field(type="Relationship")
852 1
     *
853 1
     * @return string
854
     */
855
    public function getFamilyRelationship(): string
856
    {
857
        return $this->familyRelationship;
858
    }
859
860
    /**
861
     * @API\Input(type="Relationship")
862
     *
863
     * @param string $familyRelationship
864
     */
865
    public function setFamilyRelationship(string $familyRelationship): void
866
    {
867
        $this->familyRelationship = $familyRelationship;
868
    }
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 6
    /**
881
     * @API\Input(type="BillingType")
882 6
     *
883
     * @param string $billingType
884
     */
885
    public function setBillingType(string $billingType): void
886
    {
887
        $this->billingType = $billingType;
888
    }
889
890
    /**
891 7
     * Get the user transaction account
892
     *
893 7
     * @return null|Account
894 7
     */
895 7
    public function getAccount(): ?Account
896
    {
897
        return $this->accounts->count() ? $this->accounts->first() : null;
898
    }
899
900
    /**
901 4
     * Notify the user that it has a new account
902
     * This should only be called by Account::setOwner()
903 4
     *
904 4
     * @param Account $account
905
     */
906
    public function accountAdded(Account $account): void
907
    {
908
        $this->accounts->clear();
909
        $this->accounts->add($account);
910
    }
911 1
912
    /**
913 1
     * Notify the user that a account was removed
914
     * This should only be called by Account::setOwner()
915
     */
916
    public function accountRemoved(): void
917
    {
918
        $this->accounts->clear();
919
    }
920
921
    /**
922 8
     * Get messages sent to the user
923
     *
924 8
     * @return Collection
925 8
     */
926
    public function getMessages(): Collection
927
    {
928
        return $this->messages;
929
    }
930
931
    /**
932
     * Notify the user that it has a new message
933 1
     * This should only be called by Message::setRecipient()
934
     *
935 1
     * @param Message $message
936 1
     */
937
    public function messageAdded(Message $message): void
938
    {
939
        $this->messages->add($message);
940
    }
941 4
942
    /**
943 4
     * Notify the user that a message was removed
944 4
     * This should only be called by Message::setRecipient()
945
     *
946 4
     * @param Message $message
947
     */
948
    public function messageRemoved(Message $message): void
949
    {
950
        $this->messages->removeElement($message);
951
    }
952 18
953
    /**
954 18
     * Generate a new random token to reset password
955 18
     */
956 18
    public function createToken(): string
957
    {
958
        $this->token = bin2hex(random_bytes(16));
959
        $this->tokenCreationDate = new Chronos();
960
961
        return $this->token;
962
    }
963
964
    /**
965 3
     * Destroy existing token
966
     */
967 3
    private function revokeToken(): void
968 1
    {
969
        $this->token = null;
970
        $this->tokenCreationDate = null;
971 3
    }
972
973 3
    /**
974
     * Check if token is valid.
975
     *
976
     * @API\Exclude
977
     *
978
     * @return bool
979
     */
980
    public function isTokenValid(): bool
981
    {
982
        if (!$this->tokenCreationDate) {
983
            return false;
984
        }
985
986 6
        $timeLimit = $this->tokenCreationDate->addMinutes(30);
987
988 6
        return $timeLimit->isFuture();
989 6
    }
990
991 6
    /**
992 3
     * Check if the user can *really* open a door
993
     * This also takes into account the user status and role
994
     *
995 6
     * @API\Field(args={@API\Argument(name="door", type="?Application\Api\Enum\DoorType")})
996 2
     *
997
     * @param null|string $door a particular door, or null for any
998
     *
999 4
     * @return bool
1000
     */
1001
    public function getCanOpenDoor(?string $door = null): bool
1002
    {
1003
        $allowedStatus = [self::STATUS_ACTIVE];
1004
        $allowedRoles = [self::ROLE_INDIVIDUAL, self::ROLE_MEMBER, self::ROLE_RESPONSIBLE, self::ROLE_ADMINISTRATOR];
1005
1006
        if ($door && !$this->$door) {
1007
            return false;
1008
        }
1009
1010
        if (!in_array($this->status, $allowedStatus, true) || !in_array($this->role, $allowedRoles, true)) {
1011
            return false;
1012
        }
1013
1014
        return true;
1015
    }
1016
}
1017