Failed Conditions
Push — master ( 1176d7...a379d1 )
by Adrien
16:06
created

User::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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