Passed
Push — master ( eff4fb...57c190 )
by Sam
07:38
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\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 142
    public static function setCurrent(?self $user): void
56
    {
57 142
        self::$currentUser = $user;
58
59
        // Initialize ACL filter with current user if a logged in one exists
60
        /** @var UserRepository $userRepository */
61 142
        $userRepository = _em()->getRepository(self::class);
62 142
        $aclFilter = $userRepository->getAclFilter();
63 142
        $aclFilter->setUser($user);
64
65 142
        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
     * @var Collection<Session>
113
     * @ORM\ManyToMany(targetEntity="Session", mappedBy="facilitators")
114
     */
115
    private Collection $sessions;
116
117
    /**
118
     * @var Collection<User>
119
     * @ORM\OneToMany(targetEntity="User", mappedBy="owner")
120
     */
121
    private Collection $users;
122
123
    /**
124
     * @param string $role role for new user
125
     */
126 14
    public function __construct(string $role = self::ROLE_MEMBER)
127
    {
128 14
        $this->role = $role;
129 14
        $this->sessions = new ArrayCollection();
130 14
        $this->users = new ArrayCollection();
131
    }
132
133
    /**
134
     * Get full name.
135
     */
136 10
    public function getName(): string
137
    {
138 10
        return implode(' ', array_filter([$this->getFirstName(), $this->getLastName()]));
139
    }
140
141
    /**
142
     * Set email.
143
     *
144
     * @API\Input(type="Email")
145
     *
146
     * @param string $email
147
     */
148 3
    public function setEmail(?string $email): void
149
    {
150 3
        $this->email = $email;
151
    }
152
153
    /**
154
     * Get email.
155
     *
156
     * @API\Field(type="Email")
157
     */
158 18
    public function getEmail(): ?string
159
    {
160 18
        return $this->email;
161
    }
162
163
    /**
164
     * Use email as technical identifier of user.
165
     *
166
     * @API\Exclude
167
     */
168 9
    public function getLogin(): ?string
169
    {
170 9
        return $this->getEmail();
171
    }
172
173
    /**
174
     * Get the user role.
175
     *
176
     * @API\Field(type="UserRole")
177
     */
178 47
    public function getRole(): string
179
    {
180 47
        return $this->role;
181
    }
182
183
    /**
184
     * Sets the user role.
185
     *
186
     * @API\Input(type="UserRole")
187
     */
188 7
    public function setRole(string $role): void
189
    {
190 7
        if (!Role::canUpdate(self::getCurrent(), $this->role, $role)) {
191 3
            $currentRole = self::getCurrent() ? self::getCurrent()->getRole() : self::ROLE_ANONYMOUS;
192
193 3
            throw new Exception($currentRole . ' is not allowed to change role from ' . $this->role . ' to ' . $role);
194
        }
195
196 4
        $this->role = $role;
197
    }
198
199 1
    public function initialize(): void
200
    {
201 1
        $this->role = self::ROLE_MEMBER; // Bypass security
202
    }
203
204 1
    public function getPhone(): string
205
    {
206 1
        return $this->phone;
207
    }
208
209
    public function setPhone(string $phone): void
210
    {
211
        $this->phone = $phone;
212
    }
213
214
    public function getSessions(): Collection
215
    {
216
        return $this->sessions;
217
    }
218
219
    /**
220
     * Notify the user that it has a new session.
221
     * This should only be called by Session::addFacilitator().
222
     */
223
    public function sessionAdded(Session $session): void
224
    {
225
        $this->sessions->add($session);
226
    }
227
228
    /**
229
     * Notify the user that a session was removed.
230
     * This should only be called by Session::removeFacilitator().
231
     */
232
    public function sessionRemoved(Session $session): void
233
    {
234
        $this->sessions->removeElement($session);
235
    }
236
237 1
    public function getMembership(): string
238
    {
239 1
        return $this->membership;
240
    }
241
242
    /**
243
     * @API\Exclude
244
     */
245
    public function setMembership(string $membership): void
246
    {
247
        $this->membership = $membership;
248
    }
249
250 3
    public function getWebTemporaryAccess(): bool
251
    {
252 3
        return $this->webTemporaryAccess;
253
    }
254
255
    /**
256
     * @API\Exclude
257
     */
258 2
    public function setWebTemporaryAccess(bool $webTemporaryAccess): void
259
    {
260 2
        $this->webTemporaryAccess = $webTemporaryAccess;
261
    }
262
263
    public function setIsPublicFacilitator(bool $isPublicFacilitator): void
264
    {
265
        $this->isPublicFacilitator = $isPublicFacilitator;
266
    }
267
268
    public function isPublicFacilitator(): bool
269
    {
270
        return $this->isPublicFacilitator;
271
    }
272
273
    /**
274
     * Get the first login date.
275
     */
276
    public function getFirstLogin(): ?Chronos
277
    {
278
        /** @var LogRepository $logRepository */
279
        $logRepository = _em()->getRepository(Log::class);
280
281
        return $logRepository->getLoginDate($this, true);
282
    }
283
284
    /**
285
     * Get the last login date.
286
     */
287
    public function getLastLogin(): ?Chronos
288
    {
289
        /** @var LogRepository $logRepository */
290
        $logRepository = _em()->getRepository(Log::class);
291
292
        return $logRepository->getLoginDate($this, false);
293
    }
294
295
    /**
296
     * Override parent to prevents users created from administration to be family of the administrator.
297
     *
298
     * The owner must be explicitly set for all users.
299
     */
300 2
    protected function getOwnerForCreation(): ?self
301
    {
302 2
        return null;
303
    }
304
305
    /**
306
     * Set subscription type.
307
     *
308
     * @API\Exclude
309
     */
310
    public function setSubscriptionType(?string $subscriptionType): void
311
    {
312
        $this->subscriptionType = $subscriptionType;
313
    }
314
315
    /**
316
     * Get subscription type.
317
     *
318
     * @API\Field(type="?ProductType")
319
     */
320 2
    public function getSubscriptionType(): ?string
321
    {
322 2
        return $this->subscriptionType;
323
    }
324
}
325