Failed Conditions
Push — master ( 7ddd91...986579 )
by
unknown
06:07
created

User::isActive()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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