Failed Conditions
Push — master ( ce2a97...d73709 )
by Adrien
13:38 queued 11:33
created

User::isPublicFacilitator()   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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Model;
6
7
use Application\Api\Enum\UserRoleType;
8
use Application\Api\Input\Operator\RegexpOperatorType;
9
use Application\DBAL\Types\MembershipType;
10
use Application\Repository\LogRepository;
11
use Application\Repository\UserRepository;
12
use Application\Service\Role;
13
use Application\Traits\HasAddress;
14
use Application\Traits\HasSubscriptionLastReview;
15
use Application\Traits\IsImportable;
16
use Cake\Chronos\Chronos;
17
use Doctrine\Common\Collections\ArrayCollection;
18
use Doctrine\Common\Collections\Collection;
19
use Doctrine\ORM\Mapping as ORM;
20
use Ecodev\Felix\Api\Exception;
21
use Ecodev\Felix\Api\Scalar\EmailType;
22
use Ecodev\Felix\Model\CurrentUser;
23
use Ecodev\Felix\Model\Traits\HasPassword;
24
use GraphQL\Doctrine\Attribute as API;
25
26
/**
27
 * User.
28
 */
29
#[API\Filter(field: 'custom', operator: RegexpOperatorType::class, type: 'string')]
30
#[ORM\Entity(UserRepository::class)]
31
#[ORM\HasLifecycleCallbacks]
32
#[ORM\AssociationOverrides([new ORM\AssociationOverride(name: 'owner', inversedBy: 'users')])]
33
class User extends AbstractModel implements \Ecodev\Felix\Model\HasPassword, \Ecodev\Felix\Model\User
34
{
35
    final public const ROLE_ANONYMOUS = 'anonymous';
36
    final public const ROLE_MEMBER = 'member';
37
    final public const ROLE_FACILITATOR = 'facilitator';
38
    final public const ROLE_ADMINISTRATOR = 'administrator';
39
40
    use HasAddress;
41
    use HasPassword;
42
    use HasSubscriptionLastReview;
43
    use IsImportable;
44
45
    private static ?User $currentUser = null;
46
47
    /**
48
     * Set currently logged in user
49
     * WARNING: this method should only be called from \Application\Authentication\AuthenticationListener.
50
     */
51 140
    public static function setCurrent(?self $user): void
52
    {
53 140
        self::$currentUser = $user;
54
55
        // Initialize ACL filter with current user if a logged in one exists
56
        /** @var UserRepository $userRepository */
57 140
        $userRepository = _em()->getRepository(self::class);
58 140
        $aclFilter = $userRepository->getAclFilter();
59 140
        $aclFilter->setUser($user);
60
61 140
        CurrentUser::set($user);
62
    }
63
64
    /**
65
     * Returns currently logged user or null.
66
     */
67 84
    public static function getCurrent(): ?self
68
    {
69 84
        return self::$currentUser;
70
    }
71
72
    #[ORM\Column(type: 'string', length: 191, unique: true)]
73
    private ?string $email = null;
74
75
    #[ORM\Column(type: 'UserRole', options: ['default' => self::ROLE_MEMBER])]
76
    private string $role = self::ROLE_MEMBER;
77
78
    #[ORM\Column(type: 'Membership', options: ['default' => MembershipType::NONE])]
79
    private string $membership = MembershipType::NONE;
80
81
    #[ORM\Column(type: 'ProductType', nullable: true)]
82
    private ?string $subscriptionType = null;
83
84
    #[ORM\Column(type: 'string', length: 25, options: ['default' => ''])]
85
    private string $phone = '';
86
87
    #[ORM\Column(type: 'boolean', options: ['default' => 0])]
88
    private bool $webTemporaryAccess = false;
89
90
    #[ORM\Column(type: 'boolean', options: ['default' => 0])]
91
    private bool $isPublicFacilitator = false;
92
93
    #[ORM\Column(type: 'datetime', nullable: true)]
94
    private ?Chronos $firstLogin = null;
95
96
    #[ORM\Column(type: 'datetime', nullable: true)]
97
    private ?Chronos $lastLogin = null;
98
99
    /**
100
     * @var Collection<Session>
101
     */
102
    #[ORM\ManyToMany(targetEntity: Session::class, mappedBy: 'facilitators')]
103
    private Collection $sessions;
104
105
    /**
106
     * @var Collection<User>
107
     */
108
    #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'owner')]
109
    private Collection $users;
110
111
    /**
112
     * @param string $role role for new user
113
     */
114 14
    public function __construct(string $role = self::ROLE_MEMBER)
115
    {
116 14
        $this->role = $role;
117 14
        $this->sessions = new ArrayCollection();
118 14
        $this->users = new ArrayCollection();
119
    }
120
121
    /**
122
     * Get full name.
123
     */
124 10
    public function getName(): string
125
    {
126 10
        return implode(' ', array_filter([$this->getFirstName(), $this->getLastName()]));
127
    }
128
129
    /**
130
     * Set email.
131
     */
132 3
    #[API\Input(type: EmailType::class)]
133
    public function setEmail(?string $email): void
134
    {
135 3
        $this->email = $email;
136
    }
137
138
    /**
139
     * Get email.
140
     */
141 20
    #[API\Field(type: EmailType::class)]
142
    public function getEmail(): ?string
143
    {
144 20
        return $this->email;
145
    }
146
147
    /**
148
     * Use email as a technical identifier of user.
149
     */
150 11
    #[API\Exclude]
151
    public function getLogin(): ?string
152
    {
153 11
        return $this->getEmail();
154
    }
155
156
    /**
157
     * Get the user role.
158
     */
159 45
    #[API\Field(type: UserRoleType::class)]
160
    public function getRole(): string
161
    {
162 45
        return $this->role;
163
    }
164
165
    /**
166
     * Sets the user role.
167
     */
168 7
    #[API\Input(type: UserRoleType::class)]
169
    public function setRole(string $role): void
170
    {
171 7
        if (!Role::canUpdate(self::getCurrent(), $this->role, $role)) {
172 3
            $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
173
174 3
            throw new Exception($currentRole . ' is not allowed to change role from ' . $this->role . ' to ' . $role);
175
        }
176
177 4
        $this->role = $role;
178
    }
179
180 1
    public function initialize(): void
181
    {
182 1
        $this->role = self::ROLE_MEMBER; // Bypass security
183
    }
184
185
    public function getPhone(): string
186
    {
187
        return $this->phone;
188
    }
189
190
    public function setPhone(string $phone): void
191
    {
192
        $this->phone = $phone;
193
    }
194
195
    public function getSessions(): Collection
196
    {
197
        return $this->sessions;
198
    }
199
200
    /**
201
     * Notify the user that it has a new session.
202
     * This should only be called by Session::addFacilitator().
203
     */
204
    public function sessionAdded(Session $session): void
205
    {
206
        $this->sessions->add($session);
207
    }
208
209
    /**
210
     * Notify the user that a session was removed.
211
     * This should only be called by Session::removeFacilitator().
212
     */
213
    public function sessionRemoved(Session $session): void
214
    {
215
        $this->sessions->removeElement($session);
216
    }
217
218 1
    public function getMembership(): string
219
    {
220 1
        return $this->membership;
221
    }
222
223
    #[API\Exclude]
224
    public function setMembership(string $membership): void
225
    {
226
        $this->membership = $membership;
227
    }
228
229 3
    public function getWebTemporaryAccess(): bool
230
    {
231 3
        return $this->webTemporaryAccess;
232
    }
233
234 2
    #[API\Exclude]
235
    public function setWebTemporaryAccess(bool $webTemporaryAccess): void
236
    {
237 2
        $this->webTemporaryAccess = $webTemporaryAccess;
238
    }
239
240
    public function setIsPublicFacilitator(bool $isPublicFacilitator): void
241
    {
242
        $this->isPublicFacilitator = $isPublicFacilitator;
243
    }
244
245
    public function isPublicFacilitator(): bool
246
    {
247
        return $this->isPublicFacilitator;
248
    }
249
250
    /**
251
     * Get the first login date.
252
     */
253 1
    public function getFirstLogin(): ?Chronos
254
    {
255 1
        return $this->firstLogin;
256
    }
257
258
    /**
259
     * Get the last login date.
260
     */
261 1
    public function getLastLogin(): ?Chronos
262
    {
263 1
        return $this->lastLogin;
264
    }
265
266 3
    public function recordLogin(): void
267
    {
268 3
        _log()->info(LogRepository::LOGIN);
269
270 3
        $now = new Chronos();
271 3
        if (!$this->firstLogin) {
272 3
            $this->firstLogin = $now;
273
        }
274
275 3
        $this->lastLogin = $now;
276
    }
277
278
    /**
279
     * Override parent to prevents users created from administration to be family of the administrator.
280
     *
281
     * The owner must be explicitly set for all users.
282
     */
283 2
    protected function getOwnerForCreation(): ?self
284
    {
285 2
        return null;
286
    }
287
288
    /**
289
     * Set subscription type.
290
     */
291
    #[API\Exclude]
292
    public function setSubscriptionType(?string $subscriptionType): void
293
    {
294
        $this->subscriptionType = $subscriptionType;
295
    }
296
297
    /**
298
     * Get subscription type.
299
     */
300 2
    #[API\Field(type: '?ProductType')]
301
    public function getSubscriptionType(): ?string
302
    {
303 2
        return $this->subscriptionType;
304
    }
305
}
306