Failed Conditions
Push — master ( 8e0455...8a9c79 )
by Sam
07:46
created

User::initialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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