Passed
Push — master ( cecd41...54c5b3 )
by Adrien
08:44
created

User::setRole()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

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