Passed
Push — master ( 386ab4...67c955 )
by Adrien
06:44
created

User::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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