Passed
Push — master ( 881f5d...264228 )
by Adrien
07:17
created

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