Failed Conditions
Push — master ( 816002...3ac0a4 )
by Sam
07:15 queued 11s
created

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