Failed Conditions
Push — master ( 15fc02...10b36b )
by Sylvain
09:13
created

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