Passed
Push — master ( a3961f...62f88c )
by Marcel
21:12
created

User   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 309
Duplicated Lines 0 %

Test Coverage

Coverage 81.69%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 111
dl 0
loc 309
ccs 58
cts 71
cp 0.8169
rs 8.5599
c 1
b 0
f 0
wmc 48

47 Methods

Rating   Name   Duplication   Size   Complexity  
A setIsSubstitutionNotificationsEnabled() 0 3 1
A getIdpId() 0 2 1
A setUserType() 0 3 1
A addStudent() 0 2 1
A getPassword() 0 2 1
A isStudentOrParent() 0 2 2
A getFirstname() 0 2 1
A eraseCredentials() 0 1 1
A __toString() 0 2 1
A __construct() 0 5 1
A __serialize() 0 4 1
A setIsMessageNotificationsEnabled() 0 3 1
A getDismissedMessages() 0 2 1
A removeDismissedMessage() 0 2 1
A getLastname() 0 2 1
A isMessageNotificationsEnabled() 0 2 1
A setRoles() 0 2 1
A setIsEmailNotificationsEnabled() 0 3 1
A getUsername() 0 2 1
A setFirstname() 0 3 1
A setPushoverToken() 0 3 1
A __unserialize() 0 3 1
A getSalt() 0 2 1
A setUsername() 0 3 1
A removeStudent() 0 2 1
A addDismissedMessage() 0 2 1
A getRoles() 0 2 1
A getData() 0 2 1
A getEmail() 0 2 1
A getUserIdentifier() 0 2 1
A isTeacher() 0 2 1
A setData() 0 2 1
A getUserType() 0 2 1
A isEmailNotificationsEnabled() 0 2 1
A isSubstitutionNotificationsEnabled() 0 2 1
A getId() 0 2 1
A getStudents() 0 2 1
A isParent() 0 2 1
A setTeacher() 0 3 1
A setIdpId() 0 3 1
A setLastname() 0 3 1
A isExamNotificationsEnabled() 0 2 1
A setIsExamNotificationsEnabled() 0 3 1
A getTeacher() 0 2 1
A setEmail() 0 3 1
A getPushoverToken() 0 2 1
A isStudent() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like User often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use User, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace App\Entity;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\Collections\Collection;
7
use Doctrine\ORM\Mapping as ORM;
8
use Ramsey\Uuid\Uuid;
9
use Ramsey\Uuid\UuidInterface;
10
use Stringable;
11
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
12
use Symfony\Component\Security\Core\User\UserInterface;
13
use Symfony\Component\Validator\Constraints as Assert;
14
15
#[UniqueEntity(fields: ['username'])]
16
#[ORM\Entity]
17
class User implements UserInterface, Stringable {
18
19
    use IdTrait;
20
    use UuidTrait;
21
22
    #[ORM\Column(type: 'uuid')]
23
    private ?UuidInterface $idpId = null;
24
25
    #[ORM\Column(type: 'string', unique: true)]
26
    private ?string $username = null;
27
28
    #[Assert\NotBlank(allowNull: true)]
29
    #[ORM\Column(type: 'string', nullable: true)]
30
    private ?string $firstname = null;
31
32
    #[Assert\NotBlank(allowNull: true)]
33
    #[ORM\Column(type: 'string', nullable: true)]
34
    private ?string $lastname = null;
35
36
    #[Assert\Email]
37
    #[Assert\NotBlank(allowNull: true)]
38
    #[ORM\Column(type: 'string', nullable: true)]
39
    private ?string $email = null;
40
41
    #[ORM\ManyToOne(targetEntity: Teacher::class)]
42
    #[ORM\JoinColumn(onDelete: 'SET NULL')]
43
    private ?Teacher $teacher = null;
44
45
    /**
46
     * @var Collection<Student>
47
     */
48
    #[ORM\JoinTable(name: 'user_students')]
49
    #[ORM\JoinColumn(onDelete: 'CASCADE')]
50
    #[ORM\InverseJoinColumn(onDelete: 'CASCADE')]
51
    #[ORM\ManyToMany(targetEntity: Student::class)]
52
    private $students;
53
54
    /**
55
     * @var string[]
56
     */
57
    #[ORM\Column(type: 'json')]
58
    private array $roles = ['ROLE_USER'];
59
60
    #[ORM\Column(type: 'string', enumType: UserType::class)]
61
    private ?UserType $userType = null;
62
63
    /**
64
     * @var ArrayCollection<Message>
65
     */
66
    #[ORM\JoinTable(name: 'user_dismissed_messages')]
67
    #[ORM\JoinColumn(onDelete: 'CASCADE')]
68
    #[ORM\InverseJoinColumn(onDelete: 'CASCADE')]
69
    #[ORM\ManyToMany(targetEntity: Message::class)]
70
    private $dismissedMessages;
71
72
    #[ORM\Column(type: 'boolean')]
73
    private bool $isSubstitutionNotificationsEnabled = false;
74
75
    #[ORM\Column(type: 'boolean')]
76
    private bool $isExamNotificationsEnabled = false;
77
78
    #[ORM\Column(type: 'boolean')]
79
    private bool $isMessageNotificationsEnabled = false;
80
81
    #[ORM\Column(type: 'boolean')]
82
    private bool $isEmailNotificationsEnabled = false;
83
84
    #[ORM\Column(type: 'string', nullable: true)]
85
    private ?string $pushoverToken = null;
86
87
    /**
88
     * @var string[]
89
     */
90
    #[ORM\Column(type: 'json')]
91
    private array $data = [ ];
92
93
    public function __construct() {
94
        $this->uuid = Uuid::uuid4();
95
96
        $this->students = new ArrayCollection();
97
        $this->dismissedMessages = new ArrayCollection();
98
    }
99
100
    public function getIdpId(): ?UuidInterface {
101
        return $this->idpId;
102
    }
103
104
    public function setIdpId(UuidInterface $uuid): User {
105
        $this->idpId = $uuid;
106
        return $this;
107
    }
108
109
    public function getId(): ?int {
110
        return $this->id;
111
    }
112
113
    public function getFirstname(): ?string {
114
        return $this->firstname;
115
    }
116
117
    public function setFirstname(?string $firstname): User {
118
        $this->firstname = $firstname;
119
        return $this;
120
    }
121
122
    public function getLastname(): ?string {
123
        return $this->lastname;
124
    }
125
126 28
    public function setLastname(?string $lastname): User {
127 28
        $this->lastname = $lastname;
128
        return $this;
129 28
    }
130 28
131 28
    public function getEmail(): ?string {
132
        return $this->email;
133
    }
134
135
    public function setEmail(?string $email): User {
136
        $this->email = $email;
137
        return $this;
138
    }
139
140
    public function getTeacher(): ?Teacher {
141
        return $this->teacher;
142
    }
143
144 10
    public function setTeacher(?Teacher $teacher): User {
145 10
        $this->teacher = $teacher;
146 10
        return $this;
147
    }
148
149
    public function getUserType(): UserType {
150
        return $this->userType;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->userType could return the type null which is incompatible with the type-hinted return App\Entity\UserType. Consider adding an additional type-check to rule them out.
Loading history...
151
    }
152 12
153 12
    public function setUserType(UserType $userType): User {
154
        $this->userType = $userType;
155
        return $this;
156
    }
157
158
    /**
159 7
     * @param string[] $roles
160 7
     */
161
    public function setRoles(array $roles) {
162
        $this->roles = $roles;
163
    }
164
165
    /**
166
     * @return string[]
167 7
     */
168 7
    public function getRoles(): array {
169 7
        return $this->roles;
170
    }
171
172
    public function setUsername(string $username): User {
173
        $this->username = $username;
174
        return $this;
175 7
    }
176 7
177
    public function getUsername(): string {
178
        return $this->username;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->username could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
179
    }
180
181
    public function addDismissedMessage(Message $message) {
182
        $this->dismissedMessages->add($message);
183 7
    }
184 7
185 7
    public function removeDismissedMessage(Message $message) {
186
        $this->dismissedMessages->removeElement($message);
187
    }
188
189
    /**
190
     * @return Collection<Message>
191 9
     */
192 9
    public function getDismissedMessages(): Collection {
193
        return $this->dismissedMessages;
194
    }
195
196
    public function addStudent(Student $student) {
197
        $this->students->add($student);
198
    }
199 19
200 19
    public function removeStudent(Student $student) {
201 19
        $this->students->removeElement($student);
202
    }
203
204
    /**
205
     * @return Collection<Student>
206
     */
207 9
    public function getStudents(): Collection {
208 9
        return $this->students;
209
    }
210
211
    public function isSubstitutionNotificationsEnabled(): bool {
212
        return $this->isSubstitutionNotificationsEnabled;
213
    }
214
215 4
    public function setIsSubstitutionNotificationsEnabled(bool $isSubstitutionNotificationsEnabled): User {
216 4
        $this->isSubstitutionNotificationsEnabled = $isSubstitutionNotificationsEnabled;
217 4
        return $this;
218
    }
219
220
    public function isExamNotificationsEnabled(): bool {
221
        return $this->isExamNotificationsEnabled;
222
    }
223 21
224 21
    public function setIsExamNotificationsEnabled(bool $isExamNotificationsEnabled): User {
225
        $this->isExamNotificationsEnabled = $isExamNotificationsEnabled;
226
        return $this;
227
    }
228
229
    public function isMessageNotificationsEnabled(): bool {
230
        return $this->isMessageNotificationsEnabled;
231 27
    }
232 27
233 27
    public function setIsMessageNotificationsEnabled(bool $isMessageNotificationsEnabled): User {
234
        $this->isMessageNotificationsEnabled = $isMessageNotificationsEnabled;
235
        return $this;
236
    }
237
238
    public function isEmailNotificationsEnabled(): bool {
239 16
        return $this->isEmailNotificationsEnabled;
240 16
    }
241 16
242
    public function setIsEmailNotificationsEnabled(bool $isEmailNotificationsEnabled): User {
243
        $this->isEmailNotificationsEnabled = $isEmailNotificationsEnabled;
244
        return $this;
245
    }
246 16
247 16
    /**
248
     * @return string|null
249
     */
250
    public function getPushoverToken(): ?string {
251
        return $this->pushoverToken;
252
    }
253
254 16
    /**
255 16
     * @param string|null $pushoverToken
256 16
     * @return User
257
     */
258
    public function setPushoverToken(?string $pushoverToken): User {
259
        $this->pushoverToken = $pushoverToken;
260
        return $this;
261
    }
262 17
263 17
    public function getData(string $key, $default = null) {
264
        return $this->data[$key] ?? $default;
265
    }
266 1
267 1
    public function setData(string $key, $data): void {
268 1
        $this->data[$key] = $data;
269
    }
270 1
271 1
    /**
272 1
     * @inheritDoc
273
     */
274
    public function getPassword(): ?string {
275
        return '';
276
    }
277 1
278 1
    /**
279
     * @inheritDoc
280
     */
281 16
    public function getSalt(): ?string {
282 16
        return null;
283 16
    }
284
285
    /**
286
     * @inheritDoc
287
     */
288
    public function eraseCredentials() { }
289
290
    public function getUserIdentifier(): string {
291
        return $this->getUsername();
292 15
    }
293 15
294
    public function __serialize(): array {
295
        return [
296
            'id' => $this->getId(),
297
            'username' => $this->getUsername()
298
        ];
299
    }
300
301
    public function __unserialize(array $serialized) {
302
        $this->id = $serialized['id'];
303
        $this->username = $serialized['username'];
304
    }
305
306
    public function __toString(): string {
307
        return sprintf('%s, %s (%s)', $this->getLastname(), $this->getFirstname(), $this->getUsername());
308
    }
309
310
    public function isStudent(): bool {
311
        return $this->getUserType() === UserType::Student;
312
    }
313
314
    public function isParent(): bool {
315
        return $this->getUserType() === UserType::Parent;
316
    }
317
318
    public function isStudentOrParent(): bool {
319
        return $this->isStudent() || $this->isParent();
320
    }
321
322
    public function isTeacher(): bool {
323
        return $this->getUserType() === UserType::Teacher;
324
    }
325
}