Failed Conditions
Push — master ( 1d36b7...08ff7a )
by Sam
07:43
created

User::initialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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