Passed
Push — master ( 89074f...481507 )
by
unknown
06:54
created

User::setMobilePhone()   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\Acl\Acl;
8
use Application\Api\Exception;
9
use Application\DBAL\Types\BillingTypeType;
10
use Application\DBAL\Types\RelationshipType;
11
use Application\ORM\Query\Filter\AclFilter;
12
use Application\Traits\HasAddress;
13
use Application\Traits\HasDoorAccess;
14
use Application\Traits\HasName;
15
use Application\Traits\HasRemarks;
16
use Application\Traits\HasResponsible;
17
use Application\Utility;
18
use Cake\Chronos\Chronos;
19
use Cake\Chronos\Date;
20
use Doctrine\Common\Collections\ArrayCollection;
21
use Doctrine\Common\Collections\Collection;
22
use Doctrine\ORM\Mapping as ORM;
23
use GraphQL\Doctrine\Annotation as API;
24
25
/**
26
 * User
27
 *
28
 * @ORM\Entity(repositoryClass="Application\Repository\UserRepository")
29
 */
30
class User extends AbstractModel
31
{
32
    const ROLE_ANONYMOUS = 'anonymous';
33
    const ROLE_INACTIVE = 'inactive';
34
    const ROLE_BOOKING_ONLY = 'booking_only';
35
    const ROLE_MEMBER = 'member';
36
    const ROLE_RESPONSIBLE = 'responsible';
37
    const ROLE_ADMINISTRATOR = 'administrator';
38
39
    use HasName;
40
    use HasResponsible;
41
    use HasDoorAccess;
42
    use HasRemarks;
43
    use HasAddress;
44
45
    /**
46
     * @var User
47
     */
48
    private static $currentUser;
49
50
    /**
51
     * Set currently logged in user
52
     * WARNING: this method should only be called from \Application\Autgtfdrhentication\AuthenticationListener
53
     *
54
     * @param \Application\Model\User $user
55
     */
56 31
    public static function setCurrent(?self $user): void
57
    {
58 31
        self::$currentUser = $user;
59
60
        // Initalize ACL filter with current user if a logged in one exists
61 31
        _em()->getFilters()->getFilter(AclFilter::class)->setUser($user);
62 31
    }
63
64
    /**
65
     * Returns currently logged user or null
66
     *
67
     * @return null|self
68
     */
69 23
    public static function getCurrent(): ?self
70
    {
71 23
        return self::$currentUser;
72
    }
73
74
    /**
75
     * @var string
76
     *
77
     * @ORM\Column(type="string", length=50, unique=true)
78
     */
79
    private $login;
80
81
    /**
82
     * @var null|string
83
     *
84
     * @ORM\Column(type="string", length=255)
85
     */
86
    private $password;
87
88
    /**
89
     * @var string
90
     * @ORM\Column(type="string", length=191)
91
     */
92
    private $email;
93
94
    /**
95
     * @var string
96
     * @ORM\Column(type="UserRole", options={"default" = User::ROLE_MEMBER})
97
     */
98
    private $role = self::ROLE_MEMBER;
99
100
    /**
101
     * @var null|Chronos
102
     * @ORM\Column(type="datetime", nullable=true)
103
     */
104
    private $lastLogin;
105
106
    /**
107
     * @var null|Chronos
108
     * @ORM\Column(type="datetime", nullable=true)
109
     */
110
    private $activeFrom;
111
112
    /**
113
     * @var null|Chronos
114
     * @ORM\Column(type="datetime", nullable=true)
115
     */
116
    private $activeUntil;
117
118
    /**
119
     * @var null|Chronos
120
     * @ORM\Column(type="datetime", nullable=true)
121
     */
122
    private $welcomeSessionDate;
123
124
    /**
125
     * @var int sex according to ISO/IEC 5218
126
     * @ORM\Column(type="smallint", options={"default" = 0}))
127
     */
128
    private $sex = 0;
129
130
    /**
131
     * @var string
132
     * @ORM\Column(type="string", length=25, options={"default" = ""})
133
     */
134
    private $phone = '';
135
136
    /**
137
     * @var string
138
     * @ORM\Column(type="string", length=25, options={"default" = ""})
139
     */
140
    private $mobilePhone = '';
141
142
    /**
143
     * @var string
144
     * @ORM\Column(type="string", length=25, options={"default" = ""})
145
     */
146
    private $ichtusSwissSailing = '';
147
148
    /**
149
     * @var null|Date
150
     * @ORM\Column(type="date", nullable=true)
151
     */
152
    private $birthday;
153
154
    /**
155
     * @var bool
156
     * @ORM\Column(type="boolean", options={"default" = 0})
157
     */
158
    private $termsAgreement = false;
159
160
    /**
161
     * @var bool
162
     * @ORM\Column(type="boolean", options={"default" = 0})
163
     */
164
    private $hasInsurance = false;
165
166
    /**
167
     * @var bool
168
     * @ORM\Column(type="boolean", options={"default" = 0})
169
     */
170
    private $receivesNewsletter = false;
171
172
    /**
173
     * @var string
174
     * @ORM\Column(type="Relationship", options={"default" = RelationshipType::HOUSEHOLDER})
175
     */
176
    private $familyRelationship = RelationshipType::HOUSEHOLDER;
177
178
    /**
179
     * @var string
180
     * @ORM\Column(type="BillingType", options={"default" = BillingTypeType::ALL_ELECTRONIC})
181
     */
182
    private $billingType = BillingTypeType::ALL_ELECTRONIC;
183
184
    /**
185
     * @var Collection
186
     * @ORM\OneToMany(targetEntity="Booking", mappedBy="responsible")
187
     */
188
    private $bookings;
189
190
    /**
191
     * @var Collection
192
     * @ORM\ManyToMany(targetEntity="License", mappedBy="users")
193
     */
194
    private $licenses;
195
196
    /**
197
     * @var Collection
198
     * @ORM\ManyToMany(targetEntity="UserTag", mappedBy="users")
199
     */
200
    private $userTags;
201
202
    /**
203
     * @var Collection
204
     * @ORM\OneToMany(targetEntity="ExpenseClaim", mappedBy="user")
205
     */
206
    private $expenseClaims;
207
208
    /**
209
     * @var Collection
210
     * @ORM\OneToMany(targetEntity="Message", mappedBy="recipient")
211
     */
212
    private $messages;
213
214
    /**
215
     * @var Account
216
     *
217
     * @ORM\OneToOne(targetEntity="Account", inversedBy="user")
218
     * @ORM\JoinColumns({
219
     *     @ORM\JoinColumn(onDelete="SET NULL")
220
     * })
221
     */
222
    private $account;
223
224
    /**
225
     * Constructor
226
     *
227
     * @param string $role role for new user
228
     */
229 25
    public function __construct(string $role = self::ROLE_MEMBER)
230
    {
231 25
        $this->role = $role;
232 25
        $this->bookings = new ArrayCollection();
233 25
        $this->licenses = new ArrayCollection();
234 25
        $this->userTags = new ArrayCollection();
235 25
        $this->expenseClaims = new ArrayCollection();
236 25
        $this->messages = new ArrayCollection();
237 25
    }
238
239
    /**
240
     * Set login (eg: johndoe)
241
     *
242
     * @API\Input(type="Application\Api\Scalar\LoginType")
243
     *
244
     * @param string $login
245
     */
246
    public function setLogin(string $login): void
247
    {
248
        $this->login = $login;
249
    }
250
251
    /**
252
     * Get login (eg: johndoe)
253
     *
254
     * @API\Field(type="Application\Api\Scalar\LoginType")
255
     *
256
     * @return string
257
     */
258 1
    public function getLogin(): string
259
    {
260 1
        return $this->login;
261
    }
262
263
    /**
264
     * Encrypt and change the user password
265
     *
266
     * @param string $password
267
     */
268 3
    public function setPassword(string $password): void
269
    {
270
        // Ignore empty password that could be sent "by mistake" by the client
271
        // when agreeing to terms
272 3
        if ($password === '') {
273 1
            return;
274
        }
275
276 3
        $this->password = password_hash($password, PASSWORD_DEFAULT);
277 3
    }
278
279
    /**
280
     * Returns the hashed password
281
     *
282
     * @API\Exclude
283
     *
284
     * @return null|string
285
     */
286 3
    public function getPassword(): ?string
287
    {
288 3
        return $this->password;
289
    }
290
291
    /**
292
     * Set email
293
     *
294
     * @API\Input(type="Email")
295
     *
296
     * @param string $email
297
     */
298 1
    public function setEmail(string $email): void
299
    {
300 1
        $this->email = $email;
301 1
    }
302
303
    /**
304
     * Get email
305
     *
306
     * @API\Field(type="Email")
307
     *
308
     * @return string
309
     */
310 1
    public function getEmail(): string
311
    {
312 1
        return $this->email;
313
    }
314
315
    /**
316
     * Returns whether the user is administrator and thus have can do anything.
317
     *
318
     * @API\Field(type="Application\Api\Enum\UserRoleType")
319
     */
320 17
    public function getRole(): string
321
    {
322 17
        return $this->role;
323
    }
324
325
    /**
326
     * Sets the user role
327
     *
328
     * The current user is allowed to promote another user up to the same role as himself. So
329
     * a Senior can promote a Student to Senior. Or an Admin can promote a Junior to Admin.
330
     *
331
     * But the current user is **not** allowed to demote a user who has a higher role than himself.
332
     * That means that a Senior cannot demote an Admin to Student.
333
     *
334
     * @param string $role
335
     */
336 7
    public function setRole(string $role): void
337
    {
338 7
        if ($role === $this->role) {
339 2
            return;
340
        }
341
342 5
        $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
343
        $orderedRoles = [
344 5
            self::ROLE_ANONYMOUS,
345 5
            self::ROLE_MEMBER,
346 5
            self::ROLE_ADMINISTRATOR,
347
        ];
348
349 5
        $newFound = false;
350 5
        $oldFound = false;
351 5
        foreach ($orderedRoles as $r) {
352 5
            if ($r === $this->role) {
353 3
                $oldFound = true;
354
            }
355 5
            if ($r === $role) {
356 2
                $newFound = true;
357
            }
358
359 5
            if ($r === $currentRole) {
360 5
                break;
361
            }
362
        }
363
364 5
        if (!$newFound || !$oldFound) {
365 3
            throw new Exception($currentRole . ' is not allowed to change role to ' . $role);
366
        }
367
368 2
        $this->role = $role;
369 2
    }
370
371
    /**
372
     * The date from when the user is active.
373
     *
374
     * @return null|Chronos
375
     */
376
    public function getActiveFrom(): ?Chronos
377
    {
378
        return $this->activeFrom;
379
    }
380
381
    /**
382
     * The date from when the user is active.
383
     *
384
     * @param null|Chronos $activeFrom
385
     */
386
    public function setActiveFrom(?Chronos $activeFrom): void
387
    {
388
        $this->activeFrom = $activeFrom;
389
    }
390
391
    /**
392
     * The date until the user is active. Or `null` if there is not limit in time
393
     *
394
     * @return null|Chronos
395
     */
396 5
    public function getActiveUntil(): ?Chronos
397
    {
398 5
        return $this->activeUntil;
399
    }
400
401
    /**
402
     * The date until the user is active. Or `null` if there is not limit in time
403
     *
404
     * @param null|Chronos $activeUntil
405
     */
406 2
    public function setActiveUntil(?Chronos $activeUntil): void
407
    {
408 2
        $this->activeUntil = $activeUntil;
409 2
    }
410
411
    /**
412
     * The user account is active
413
     *
414
     * @return bool
415
     */
416
    public function isActive(): bool
417
    {
418
        return ($this->getActiveFrom() === null || Chronos::now() > $this->getActiveFrom()) && ($this->getActiveFrom() === null || Chronos::now() < $this->getActiveUntil());
419
    }
420
421
    /**
422
     * Get a list of global permissions for this user
423
     *
424
     * @API\Field(type="GlobalPermissionsList")
425
     *
426
     * @return array
427
     */
428 3
    public function getGlobalPermissions(): array
429
    {
430 3
        $acl = new Acl();
431
        $types = [
432 3
            Country::class,
433
            License::class,
434
            self::class,
435
        ];
436
437 3
        $permissions = ['create'];
438 3
        $result = [];
439
440 3
        $previousUser = self::getCurrent();
441 3
        self::setCurrent($this);
442 3
        foreach ($types as $type) {
443 3
            $instance = new $type();
444 3
            $sh = lcfirst(Utility::getShortClassName($instance));
445 3
            $result[$sh] = [];
446
447 3
            foreach ($permissions as $p) {
448 3
                $result[$sh][$p] = $acl->isCurrentUserAllowed($instance, $p);
449
            }
450
        }
451
452 3
        self::setCurrent($previousUser);
453
454 3
        return $result;
455
    }
456
457
    /**
458
     * @return string
459
     */
460
    public function getPhone(): string
461
    {
462
        return $this->phone;
463
    }
464
465
    /**
466
     * @param string $phone
467
     */
468
    public function setPhone(string $phone): void
469
    {
470
        $this->phone = $phone;
471
    }
472
473
    /**
474
     * @return string
475
     */
476
    public function getMobilePhone(): string
477
    {
478
        return $this->mobilePhone;
479
    }
480
481
    /**
482
     * @param string $mobilePhone
483
     */
484
    public function setMobilePhone(string $mobilePhone): void
485
    {
486
        $this->mobilePhone = $mobilePhone;
487
    }
488
489
    /**
490
     * @return null|Date
491
     */
492
    public function getBirthday(): ?Date
493
    {
494
        return $this->birthday;
495
    }
496
497
    /**
498
     * @param null|Date $birthday
499
     */
500
    public function setBirthday(?Date $birthday): void
501
    {
502
        $this->birthday = $birthday;
503
    }
504
505
    /**
506
     * Get bookings
507
     *
508
     * @return Collection
509
     */
510 1
    public function getBookings(): Collection
511
    {
512 1
        return $this->bookings;
513
    }
514
515
    /**
516
     * Notify the user that it has a new booking.
517
     * This should only be called by Booking::setResponsible()
518
     *
519
     * @param Booking $booking
520
     */
521 1
    public function bookingAdded(Booking $booking): void
522
    {
523 1
        $this->bookings->add($booking);
524 1
    }
525
526
    /**
527
     * Notify the user that it has a booking was removed.
528
     * This should only be called by Booking::setResponsible()
529
     *
530
     * @param Booking $booking
531
     */
532 1
    public function bookingRemoved(Booking $booking): void
533
    {
534 1
        $this->bookings->removeElement($booking);
535 1
    }
536
537
    /**
538
     * @return Collection
539
     */
540 1
    public function getLicenses(): Collection
541
    {
542 1
        return $this->licenses;
543
    }
544
545
    /**
546
     * @return Collection
547
     */
548 1
    public function getUserTags(): Collection
549
    {
550 1
        return $this->userTags;
551
    }
552
553
    /**
554
     * Notify the user that it has a new license.
555
     * This should only be called by License::addUser()
556
     *
557
     * @param License $license
558
     */
559 1
    public function licenseAdded(License $license): void
560
    {
561 1
        $this->licenses->add($license);
562 1
    }
563
564
    /**
565
     * Notify the user that it a license was removed.
566
     * This should only be called by License::removeUser()
567
     *
568
     * @param License $license
569
     */
570 1
    public function licenseRemoved(License $license): void
571
    {
572 1
        $this->licenses->removeElement($license);
573 1
    }
574
575
    /**
576
     * Notify the user that it has a new userTag.
577
     * This should only be called by UserTag::addUser()
578
     *
579
     * @param UserTag $userTag
580
     */
581 1
    public function userTagAdded(UserTag $userTag): void
582
    {
583 1
        $this->userTags->add($userTag);
584 1
    }
585
586
    /**
587
     * Notify the user that a userTag was removed.
588
     * This should only be called by UserTag::removeUser()
589
     *
590
     * @param UserTag $userTag
591
     */
592 1
    public function userTagRemoved(UserTag $userTag): void
593
    {
594 1
        $this->userTags->removeElement($userTag);
595 1
    }
596
597
    /**
598
     * @return bool
599
     */
600
    public function isTermsAgreement(): bool
601
    {
602
        return $this->termsAgreement;
603
    }
604
605
    /**
606
     * @param bool $termsAgreement
607
     */
608
    public function setTermsAgreement(bool $termsAgreement): void
609
    {
610
        $this->termsAgreement = $termsAgreement;
611
    }
612
613
    /**
614
     * @return bool
615
     */
616
    public function getHasInsurance(): bool
617
    {
618
        return $this->hasInsurance;
619
    }
620
621
    /**
622
     * @param bool $hasInsurance
623
     */
624
    public function setHasInsurance(bool $hasInsurance): void
625
    {
626
        $this->hasInsurance = $hasInsurance;
627
    }
628
629
    /**
630
     * @return null|Chronos
631
     */
632
    public function getWelcomeSessionDate(): ?Chronos
633
    {
634
        return $this->welcomeSessionDate;
635
    }
636
637
    /**
638
     * @param null|Chronos $welcomeSessionDate
639
     */
640
    public function setWelcomeSessionDate(?Chronos $welcomeSessionDate): void
641
    {
642
        $this->welcomeSessionDate = $welcomeSessionDate;
643
    }
644
645
    /**
646
     * @return bool
647
     */
648
    public function isReceivesNewsletter(): bool
649
    {
650
        return $this->receivesNewsletter;
651
    }
652
653
    /**
654
     * @param bool $receivesNewsletter
655
     */
656
    public function setReceivesNewsletter(bool $receivesNewsletter): void
657
    {
658
        $this->receivesNewsletter = $receivesNewsletter;
659
    }
660
661
    /**
662
     * Get the ISO/IEC 5218 sex
663
     *
664
     * @API\Field(type="Sex")
665
     *
666
     * @return int
667
     */
668
    public function getSex(): int
669
    {
670
        return $this->sex;
671
    }
672
673
    /**
674
     * Set the ISO/IEC 5218 sex
675
     *
676
     * @API\Input(type="Sex")
677
     *
678
     * @param int $sex
679
     */
680
    public function setSex(int $sex): void
681
    {
682
        $this->sex = $sex;
683
    }
684
685
    /**
686
     * @return string
687
     */
688
    public function getIchtusSwissSailing(): string
689
    {
690
        return $this->ichtusSwissSailing;
691
    }
692
693
    /**
694
     * @param string $ichtusSwissSailing
695
     */
696
    public function setIchtusSwissSailing(string $ichtusSwissSailing): void
697
    {
698
        $this->ichtusSwissSailing = $ichtusSwissSailing;
699
    }
700
701
    /**
702
     * Get the last login
703
     *
704
     * @return null|Chronos
705
     */
706
    public function getLastLogin(): ?Chronos
707
    {
708
        return $this->lastLogin;
709
    }
710
711
    /**
712
     * @param null|Chronos $lastLogin
713
     */
714 2
    public function setLastLogin(?Chronos $lastLogin): void
715
    {
716 2
        $this->lastLogin = $lastLogin;
717 2
    }
718
719
    /**
720
     * @API\Field(type="Relationship")
721
     *
722
     * @return string
723
     */
724 1
    public function getFamilyRelationship(): string
725
    {
726 1
        return $this->familyRelationship;
727
    }
728
729
    /**
730
     * @API\Input(type="Relationship")
731
     *
732
     * @param string $familyRelationship
733
     */
734
    public function setFamilyRelationship(string $familyRelationship): void
735
    {
736
        $this->familyRelationship = $familyRelationship;
737
    }
738
739
    /**
740
     * @return string
741
     */
742
    public function getBillingType(): string
743
    {
744
        return $this->billingType;
745
    }
746
747
    /**
748
     * @param string $billingType
749
     */
750
    public function setBillingType(string $billingType): void
751
    {
752
        $this->billingType = $billingType;
753
    }
754
755
    /**
756
     * Get the user transaction account
757
     *
758
     * @return null|Account
759
     */
760 1
    public function getAccount(): ?Account
761
    {
762 1
        return $this->account;
763
    }
764
765
    /**
766
     * Assign a transaction account to the user
767
     *
768
     * @param null|Account $account
769
     */
770 1
    public function setAccount(?Account $account): void
771
    {
772 1
        $previousAccount = $this->getAccount();
773
774 1
        if ($account) {
775 1
            if ($this->getFamilyRelationship() !== RelationshipType::HOUSEHOLDER) {
776
                throw new Exception('Only the house holder can have an account');
777
            }
778 1
            $account->userAdded($this);
779
        }
780
781 1
        if ($previousAccount) {
782 1
            $previousAccount->setUser(null);
783
        }
784
785 1
        $this->account = $account;
786 1
    }
787
788
    /**
789
     * Get messages sent to the user
790
     *
791
     * @return Collection
792
     */
793 1
    public function getMessages(): Collection
794
    {
795 1
        return $this->messages;
796
    }
797
798
    /**
799
     * Notify the user that it has a new message
800
     * This should only be called by Message::setRecipient()
801
     *
802
     * @param Message $message
803
     */
804 1
    public function messageAdded(Message $message): void
805
    {
806 1
        $this->messages->add($message);
807 1
    }
808
809
    /**
810
     * Notify the user that a message was removed
811
     * This should only be called by Message::setRecipient()
812
     *
813
     * @param Message $message
814
     */
815 1
    public function messageRemoved(Message $message): void
816
    {
817 1
        $this->messages->removeElement($message);
818 1
    }
819
820
    /**
821
     * Get expense claims submitted by the user
822
     *
823
     * @return Collection
824
     */
825 1
    public function getExpenseClaims(): Collection
826
    {
827 1
        return $this->expenseClaims;
828
    }
829
830
    /**
831
     * Notify the user when a new expense claim was added
832
     * This should only be called by ExpenseClaim::setUser()
833
     *
834
     * @param ExpenseClaim $expense
835
     */
836 1
    public function expenseClaimAdded(ExpenseClaim $expense): void
837
    {
838 1
        $this->expenseClaims->add($expense);
839 1
    }
840
841
    /**
842
     * Notify the user that when an expense claim was removed
843
     * This should only be called by ExpenseClaim::setUser()
844
     *
845
     * @param ExpenseClaim $expense
846
     */
847 1
    public function expenseClaimRemoved(ExpenseClaim $expense): void
848
    {
849 1
        $this->expenseClaims->removeElement($expense);
850 1
    }
851
}
852