Passed
Push — master ( 7a508d...4b0712 )
by Angel Fernando Quiroz
10:57
created

User   F

Complexity

Total Complexity 292

Size/Duplication

Total Lines 2542
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 937
c 4
b 0
f 0
dl 0
loc 2542
rs 1.663
wmc 292

244 Methods

Rating   Name   Duplication   Size   Complexity  
A getPlainPassword() 0 3 1
A getIri() 0 7 2
A getIdentifier() 0 3 1
A getLastLogin() 0 3 1
A setExpiresAt() 0 5 1
A setLastLogin() 0 5 1
A getUsername() 0 3 1
A setPasswordRequestedAt() 0 5 1
A getPasswordRequestedAt() 0 3 1
A getSlug() 0 3 1
A getConfirmationToken() 0 3 1
A isOnline() 0 3 1
A setConfirmationToken() 0 5 1
A getCredentialsExpireAt() 0 3 1
A setUsername() 0 5 1
A getExpiresAt() 0 3 1
A setPlainPassword() 0 8 1
A setCredentialsExpireAt() 0 5 1
A getId() 0 3 1
A setSlug() 0 3 1
A isPasswordRequestNonExpired() 0 4 2
A addFriend() 0 3 1
A getHrDeptId() 0 3 1
A getCompetences() 0 3 1
A getUsernameCanonical() 0 3 1
A getCourseGroupsAsMember() 0 3 1
A setOpenarea() 0 5 1
A setEmailCanonical() 0 5 1
A setLastname() 0 5 1
A getTrackEAccessCompleteList() 0 3 1
A getRoles() 0 10 2
A getFriendsWithMe() 0 3 1
A setDropBoxSentFiles() 0 5 1
A getGradeBookComments() 0 3 1
A getCurrentlyAccessibleSessions() 0 10 3
A getFriends() 0 3 1
A getOfficialCode() 0 3 1
A setUsernameCanonical() 0 5 1
A setPortals() 0 3 1
A getDefaultIllustration() 0 5 2
A getCreatorId() 0 3 1
A setLocale() 0 5 1
A isCredentialsNonExpired() 0 3 1
A isTeacher() 0 3 1
A setCreatorId() 0 5 1
A getFirstname() 0 3 1
A getUuid() 0 3 1
A setFullName() 0 5 1
A getSessionsAsGeneralCoach() 0 3 1
A isHRM() 0 3 1
A setCurrentUrl() 0 6 1
A getUserRelCourseVotes() 0 3 1
A getUserCourseCategories() 0 3 1
A setProfileCompleted() 0 5 1
A isSessionAdmin() 0 3 1
A isActive() 0 3 1
A getGradeBookCategories() 0 3 1
A setCommentedUserSkills() 0 5 1
A setTheme() 0 5 1
A setRoleFromStatus() 0 4 1
A getPictureUri() 0 3 1
A getPassword() 0 3 1
A setActive() 0 5 1
A setRoles() 0 8 2
A getGroupNames() 0 8 2
A getGradeBookResultLogs() 0 3 1
A getCredentialsExpired() 0 3 1
A getPhone() 0 3 1
A getBiography() 0 3 1
A setClasses() 0 5 1
A isStudentBoss() 0 3 1
A getSalt() 0 3 1
A setPortal() 0 5 1
A getPortals() 0 3 1
A setSkipResourceNode() 0 5 1
A getLocale() 0 3 1
A getCourseGroupsAsTutorFromCourse() 0 6 1
A getRoleFromStatus() 0 10 1
A getEmailCanonical() 0 3 1
A getAchievedSkills() 0 3 1
A getEmail() 0 3 1
A getGradeBookScoreLogs() 0 3 1
A setOpenid() 0 5 1
A removeRole() 0 8 2
A setExpired() 0 5 1
A getResourceNodes() 0 3 1
A removeGroup() 0 7 2
A setParent() 0 1 1
A getPasswordConstraints() 0 6 1
A getTrackECourseAccess() 0 3 1
A eraseCredentials() 0 3 1
A setAchievedSkills() 0 5 1
A setResourceName() 0 3 1
A getWebsite() 0 3 1
A setProductions() 0 5 1
A setBiography() 0 5 1
A getIsActive() 0 3 1
A getExpired() 0 3 1
A setDiplomas() 0 5 1
A getTrackEAttempts() 0 3 1
A getDRHSessions() 0 3 1
A getUserRelTags() 0 3 1
A getCommentedUserSkills() 0 3 1
A getGradeBookCertificates() 0 3 1
A hasRole() 0 3 1
A addUserAsAdmin() 0 10 2
A getDiplomas() 0 3 1
A setEmail() 0 5 1
A getTimezone() 0 3 1
A getCourseGroupsAsTutor() 0 3 1
A getIconStatus() 0 25 6
A setOfficialCode() 0 5 1
A getResourceNode() 0 3 1
A hasSkill() 0 12 3
A setSalt() 0 5 1
A getCurriculumItems() 0 3 1
A getApiToken() 0 3 1
A setExpirationDate() 0 5 1
A setHrDeptId() 0 5 1
A getTeach() 0 3 1
A getFullname() 0 8 2
A getGroups() 0 3 1
A getCurrentUrl() 0 3 1
A getCompleteNameWithClasses() 0 13 3
A setCredentialsExpired() 0 5 1
A getAddress() 0 3 1
A getCourses() 0 3 1
A getStatus() 0 3 1
A isStudent() 0 3 1
A isInvitee() 0 3 1
A setUuid() 0 5 1
A setTeach() 0 5 1
A getDateOfBirth() 0 3 1
A setFirstname() 0 5 1
A isAdmin() 0 3 1
A setCourses() 0 5 1
A setWebsite() 0 5 1
A getClasses() 0 3 1
A getLastname() 0 3 1
A getSequenceValues() 0 3 1
A getGradeBookLinkEvalLogs() 0 3 1
A getOpenarea() 0 3 1
A getGradeBookResults() 0 3 1
A getSessionsAsStudent() 0 3 1
A getActive() 0 3 1
A setResourceNode() 0 5 1
A setGradeBookCertificates() 0 5 1
A hasGroup() 0 3 1
A setAddress() 0 5 1
A getTheme() 0 3 1
A getTemplates() 0 3 1
A getSessionsRelUser() 0 3 1
A loadValidatorMetadata() 0 1 1
A getTrackEExerciseConfirmations() 0 3 1
A getProfileUrl() 0 3 1
A setPhone() 0 5 1
A getUserIdentifier() 0 3 1
A isAccountNonLocked() 0 3 1
A getSessionsAsAdmin() 0 3 1
A setCompetences() 0 5 1
A getSentMessages() 0 3 1
A getReceivedMessages() 0 3 1
A isSuperAdmin() 0 3 1
A getLocked() 0 3 1
A setPassword() 0 5 1
A isAccountNonExpired() 0 3 1
A setGroups() 0 7 2
A getProductions() 0 3 1
A setAdmin() 0 5 1
A getAdmin() 0 3 1
A setTimezone() 0 5 1
A addGroup() 0 7 2
A getDropBoxReceivedFiles() 0 3 1
A addResourceNode() 0 8 2
A setApiToken() 0 5 1
A setLocked() 0 5 1
A isProfileCompleted() 0 3 1
A setDateOfBirth() 0 5 1
A hasResourceNode() 0 3 1
A getCourseGroupsAsMemberFromCourse() 0 6 1
A getSessions() 0 10 3
A addUserRelUser() 0 6 1
A addSessionRelUser() 0 5 1
A setStatus() 0 5 1
A isEqualTo() 0 13 4
A getOpenid() 0 3 1
A isEnabled() 0 3 1
A getResourceIdentifier() 0 3 1
A getExpirationDate() 0 3 1
A addRole() 0 11 4
A isSkipResourceNode() 0 3 1
A getDropBoxSentFiles() 0 3 1
A __toString() 0 3 1
B __construct() 0 63 1
A getResourceName() 0 3 1
A addAuthSource() 0 8 2
A setMessageTags() 0 5 1
A getSurveyInvitations() 0 3 1
A getMfaBackupCodes() 0 3 1
A getSessionRelCourseRelUsers() 0 3 1
A getAuthSourceByAuthentication() 0 4 1
A getAuthSourcesAuthentications() 0 5 2
A getMfaLastUsed() 0 3 1
A getFirstAccessToSession() 0 11 2
A hasAuthSourceByAuthentication() 0 5 2
A addSentSocialPost() 0 8 2
A isCourseTutor() 0 3 2
A removeUserAsAdmin() 0 7 1
A getLogin() 0 3 1
A getSocialPostsFeedbacks() 0 3 1
A getLogins() 0 3 1
A setMfaService() 0 5 1
A getMfaService() 0 3 1
A setLogin() 0 5 1
A getMfaSecret() 0 3 1
A hasFriendWithRelationType() 0 5 1
A getGender() 0 3 1
A getFriendsByRelationType() 0 6 1
A getFriendsWithMeByRelationType() 0 6 1
A removeAuthSource() 0 10 3
A setSessionRelCourseRelUsers() 0 5 1
A setLogins() 0 5 1
A setMfaBackupCodes() 0 5 1
A getMessageTags() 0 3 1
A setSurveyInvitations() 0 5 1
A addSocialPostFeedback() 0 8 2
A setMfaEnabled() 0 5 1
A getAuthSources() 0 3 1
A getSentSocialPosts() 0 3 1
A getReceivedSocialPosts() 0 3 1
A setMfaLastUsed() 0 5 1
A removeAuthSources() 0 9 2
A getFriendsOfFriends() 0 10 3
A getSocialPostFeedbackBySocialPost() 0 10 2
A getSubscriptionToSession() 0 14 2
A getAuthSourcesByUrl() 0 8 1
A getMaxSortValue() 0 10 2
A isFriendWithMeByRelationType() 0 5 1
A addReceivedSocialPost() 0 8 2
A getSessionsByStatusInCourseSubscription() 0 9 1
A setMfaSecret() 0 5 1
A addAuthSourceByAuthentication() 0 10 1
A setGender() 0 5 1
A getMfaEnabled() 0 3 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
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Entity;
8
9
use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter;
10
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
11
use ApiPlatform\Metadata\ApiFilter;
12
use ApiPlatform\Metadata\ApiProperty;
13
use ApiPlatform\Metadata\ApiResource;
14
use ApiPlatform\Metadata\Delete;
15
use ApiPlatform\Metadata\Get;
16
use ApiPlatform\Metadata\GetCollection;
17
use ApiPlatform\Metadata\Post;
18
use ApiPlatform\Metadata\Put;
19
use Chamilo\CoreBundle\Controller\Api\CreateUserOnAccessUrlAction;
20
use Chamilo\CoreBundle\Controller\Api\UserSkillsController;
21
use Chamilo\CoreBundle\Dto\CreateUserOnAccessUrlInput;
22
use Chamilo\CoreBundle\Entity\Listener\UserListener;
23
use Chamilo\CoreBundle\Filter\PartialSearchOrFilter;
24
use Chamilo\CoreBundle\Repository\Node\UserRepository;
25
use Chamilo\CoreBundle\Traits\UserCreatorTrait;
26
use Chamilo\CourseBundle\Entity\CGroupRelTutor;
27
use Chamilo\CourseBundle\Entity\CGroupRelUser;
28
use Chamilo\CourseBundle\Entity\CSurveyInvitation;
29
use DateTime;
30
use DateTimeInterface;
31
use Doctrine\Common\Collections\ArrayCollection;
32
use Doctrine\Common\Collections\Collection;
33
use Doctrine\Common\Collections\Criteria;
34
use Doctrine\Common\Collections\ReadableCollection;
35
use Doctrine\ORM\Mapping as ORM;
36
use Gedmo\Timestampable\Traits\TimestampableEntity;
37
use Stringable;
38
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
39
use Symfony\Component\Security\Core\User\EquatableInterface;
40
use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
41
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
42
use Symfony\Component\Security\Core\User\UserInterface;
43
use Symfony\Component\Serializer\Annotation\Groups;
44
use Symfony\Component\Uid\Uuid;
45
use Symfony\Component\Validator\Constraints as Assert;
46
use Symfony\Component\Validator\Mapping\ClassMetadata;
47
use UserManager;
48
49
#[ApiResource(
50
    types: ['http://schema.org/Person'],
51
    operations: [
52
        new Get(
53
            openapiContext: [
54
                'description' => "Get details of one specific user, including name, e-mail and role.",
55
            ],
56
            security: "is_granted('VIEW', object)",
57
        ),
58
        new Put(security: "is_granted('EDIT', object)"),
59
        new Delete(security: "is_granted('DELETE', object)"),
60
        new GetCollection(security: "is_granted('ROLE_USER')"),
61
        new Post(security: "is_granted('ROLE_ADMIN')"),
62
        new GetCollection(
63
            uriTemplate: '/users/{id}/skills',
64
            controller: UserSkillsController::class,
65
            normalizationContext: ['groups' => ['user_skills:read']],
66
            name: 'get_user_skills'
67
        ),
68
        new Post(
69
            uriTemplate: '/advanced/create-user-on-access-url',
70
            controller: CreateUserOnAccessUrlAction::class,
71
            denormalizationContext: ['groups' => ['write']],
72
            security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_SESSION_MANAGER')",
73
            input: CreateUserOnAccessUrlInput::class,
74
            output: User::class,
75
            deserialize: true,
76
            name: 'create_user_on_access_url'
77
        ),
78
    ],
79
    normalizationContext: ['groups' => ['user:read']],
80
    denormalizationContext: ['groups' => ['user:write']],
81
    security: 'is_granted("ROLE_USER")'
82
)]
83
#[ORM\Table(name: 'user')]
84
#[ORM\Index(columns: ['status'], name: 'status')]
85
#[UniqueEntity('username')]
86
#[ORM\Entity(repositoryClass: UserRepository::class)]
87
#[ORM\EntityListeners([UserListener::class])]
88
#[ApiFilter(
89
    filterClass: SearchFilter::class,
90
    properties: [
91
        'username' => 'partial',
92
        'firstname' => 'partial',
93
        'lastname' => 'partial',
94
    ]
95
)]
96
#[ApiFilter(PartialSearchOrFilter::class, properties: ['username', 'firstname', 'lastname'])]
97
#[ApiFilter(filterClass: BooleanFilter::class, properties: ['isActive'])]
98
class User implements UserInterface, EquatableInterface, ResourceInterface, ResourceIllustrationInterface, PasswordAuthenticatedUserInterface, LegacyPasswordAuthenticatedUserInterface, ExtraFieldItemInterface, Stringable
99
{
100
    use TimestampableEntity;
101
    use UserCreatorTrait;
102
103
    public const USERNAME_MAX_LENGTH = 100;
104
    public const ROLE_DEFAULT = 'ROLE_USER';
105
    public const ANONYMOUS = 6;
106
107
    /**
108
     * Global status for the fallback user.
109
     * This special status is used for a system user that acts as a placeholder
110
     * or fallback for content ownership when regular users are deleted.
111
     * This ensures data integrity and prevents orphaned content within the system.
112
     */
113
    public const ROLE_FALLBACK = 99;
114
115
    /*public const COURSE_MANAGER = 1;
116
      public const TEACHER = 1;
117
      public const SESSION_ADMIN = 3;
118
      public const DRH = 4;
119
      public const STUDENT = 5;
120
      public const ANONYMOUS = 6;*/
121
122
    // User active field constants
123
    public const ACTIVE = 1;
124
    public const INACTIVE = 0;
125
    public const INACTIVE_AUTOMATIC = -1;
126
    public const SOFT_DELETED = -2;
127
128
    #[Groups(['user_json:read'])]
129
    #[ORM\OneToOne(targetEntity: ResourceNode::class, cascade: ['persist'])]
130
    #[ORM\JoinColumn(name: 'resource_node_id', onDelete: 'CASCADE')]
131
    public ?ResourceNode $resourceNode = null;
132
133
    /**
134
     * Resource illustration URL - Property set by ResourceNormalizer.php.
135
     */
136
    #[ApiProperty(iris: ['http://schema.org/contentUrl'])]
137
    #[Groups([
138
        'user_export',
139
        'user:read',
140
        'resource_node:read',
141
        'document:read',
142
        'media_object_read',
143
        'course:read',
144
        'course_rel_user:read',
145
        'user_json:read',
146
        'message:read',
147
        'user_rel_user:read',
148
        'social_post:read',
149
        'user_subscriptions:sessions',
150
    ])]
151
    public ?string $illustrationUrl = null;
152
153
    #[Groups([
154
        'user:read',
155
        'course:read',
156
        'resource_node:read',
157
        'user_json:read',
158
        'message:read',
159
        'user_rel_user:read',
160
        'session:item:read',
161
    ])]
162
    #[ORM\Column(name: 'id', type: 'integer')]
163
    #[ORM\Id]
164
    #[ORM\GeneratedValue]
165
    protected ?int $id = null;
166
167
    #[Assert\NotBlank]
168
    #[Groups([
169
        'user_export',
170
        'user:read',
171
        'user:write',
172
        'course:read',
173
        'course_rel_user:read',
174
        'resource_node:read',
175
        'user_json:read',
176
        'message:read',
177
        'page:read',
178
        'user_rel_user:read',
179
        'social_post:read',
180
        'track_e_exercise:read',
181
        'user_subscriptions:sessions',
182
        'student_publication_rel_user:read',
183
    ])]
184
    #[ORM\Column(name: 'username', type: 'string', length: 100, unique: true)]
185
    protected string $username;
186
187
    #[ORM\Column(name: 'api_token', type: 'string', unique: true, nullable: true)]
188
    protected ?string $apiToken = null;
189
190
    #[ApiProperty(iris: ['http://schema.org/name'])]
191
    #[Assert\NotBlank]
192
    #[Groups(['user:read', 'user:write', 'resource_node:read', 'user_json:read', 'track_e_exercise:read', 'user_rel_user:read', 'user_subscriptions:sessions', 'student_publication_rel_user:read'])]
193
    #[ORM\Column(name: 'firstname', type: 'string', length: 64, nullable: true)]
194
    protected ?string $firstname = null;
195
196
    #[Groups(['user:read', 'user:write', 'resource_node:read', 'user_json:read', 'track_e_exercise:read', 'user_rel_user:read', 'user_subscriptions:sessions', 'student_publication_rel_user:read'])]
197
    #[ORM\Column(name: 'lastname', type: 'string', length: 64, nullable: true)]
198
    protected ?string $lastname = null;
199
200
    #[Groups(['user:read', 'user:write'])]
201
    #[ORM\Column(name: 'website', type: 'string', length: 255, nullable: true)]
202
    protected ?string $website;
203
204
    #[Groups(['user:read', 'user:write'])]
205
    #[ORM\Column(name: 'biography', type: 'text', nullable: true)]
206
    protected ?string $biography;
207
208
    #[Groups(['user:read', 'user:write', 'user_json:read'])]
209
    #[ORM\Column(name: 'locale', type: 'string', length: 10)]
210
    protected string $locale;
211
212
    #[Groups(['user:write'])]
213
    protected ?string $plainPassword = null;
214
215
    #[ORM\Column(name: 'password', type: 'string', length: 255)]
216
    protected string $password;
217
218
    #[ORM\Column(name: 'username_canonical', type: 'string', length: 180)]
219
    protected string $usernameCanonical;
220
221
    #[Groups(['user:read', 'user:write', 'user_json:read'])]
222
    #[ORM\Column(name: 'timezone', type: 'string', length: 64)]
223
    protected string $timezone;
224
225
    #[ORM\Column(name: 'email_canonical', type: 'string', length: 100)]
226
    protected string $emailCanonical;
227
228
    #[Groups(['user:read', 'user:write', 'user_json:read'])]
229
    #[Assert\NotBlank]
230
    #[Assert\Email]
231
    #[ORM\Column(name: 'email', type: 'string', length: 100)]
232
    protected string $email;
233
234
    #[ORM\Column(name: 'locked', type: 'boolean')]
235
    protected bool $locked;
236
237
    #[Groups(['user:read', 'user:write'])]
238
    #[ORM\Column(name: 'expired', type: 'boolean')]
239
    protected bool $expired;
240
241
    #[ORM\Column(name: 'credentials_expired', type: 'boolean')]
242
    protected bool $credentialsExpired;
243
244
    #[ORM\Column(name: 'credentials_expire_at', type: 'datetime', nullable: true)]
245
    protected ?DateTime $credentialsExpireAt;
246
247
    #[ORM\Column(name: 'date_of_birth', type: 'datetime', nullable: true)]
248
    protected ?DateTime $dateOfBirth;
249
250
    #[Groups(['user:read', 'user:write'])]
251
    #[ORM\Column(name: 'expires_at', type: 'datetime', nullable: true)]
252
    protected ?DateTime $expiresAt;
253
254
    #[Groups(['user:read', 'user:write'])]
255
    #[ORM\Column(name: 'phone', type: 'string', length: 64, nullable: true)]
256
    protected ?string $phone = null;
257
258
    #[Groups(['user:read', 'user:write'])]
259
    #[ORM\Column(name: 'address', type: 'string', length: 250, nullable: true)]
260
    protected ?string $address = null;
261
262
    #[ORM\Column(type: 'string', length: 255)]
263
    protected string $salt;
264
265
    #[ORM\Column(name: 'gender', type: 'string', length: 1, nullable: true)]
266
    protected ?string $gender = null;
267
268
    #[Groups(['user:read'])]
269
    #[ORM\Column(name: 'last_login', type: 'datetime', nullable: true)]
270
    protected ?DateTime $lastLogin = null;
271
272
    /**
273
     * Random string sent to the user email address in order to verify it.
274
     */
275
    #[ORM\Column(name: 'confirmation_token', type: 'string', length: 255, nullable: true)]
276
    protected ?string $confirmationToken = null;
277
278
    #[ORM\Column(name: 'password_requested_at', type: 'datetime', nullable: true)]
279
    protected ?DateTime $passwordRequestedAt;
280
281
    /**
282
     * @var Collection<int, CourseRelUser>
283
     */
284
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: CourseRelUser::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
285
    protected Collection $courses;
286
287
    /**
288
     * @var Collection<int, UsergroupRelUser>
289
     */
290
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: UsergroupRelUser::class)]
291
    protected Collection $classes;
292
293
    /**
294
     * ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CDropboxPost", mappedBy="user").
295
     */
296
    protected Collection $dropBoxReceivedFiles;
297
298
    /**
299
     * ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CDropboxFile", mappedBy="userSent").
300
     */
301
    protected Collection $dropBoxSentFiles;
302
303
    /**
304
     * An array of roles. Example: ROLE_USER, ROLE_TEACHER, ROLE_ADMIN.
305
     */
306
    #[Groups(['user:read', 'user:write', 'user_json:read'])]
307
    #[ORM\Column(type: 'array')]
308
    protected array $roles = [];
309
310
    #[ORM\Column(name: 'profile_completed', type: 'boolean', nullable: true)]
311
    protected ?bool $profileCompleted = null;
312
313
    /**
314
     * ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\JuryMembers", mappedBy="user").
315
     */
316
    // protected $jurySubscriptions;
317
318
    /**
319
     * @var Collection<int, Group>
320
     */
321
    #[ORM\JoinTable(name: 'fos_user_user_group')]
322
    #[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'cascade')]
323
    #[ORM\InverseJoinColumn(name: 'group_id', referencedColumnName: 'id')]
324
    #[ORM\ManyToMany(targetEntity: Group::class, inversedBy: 'users')]
325
    protected Collection $groups;
326
327
    /**
328
     * ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\CurriculumItemRelUser", mappedBy="user").
329
     */
330
    protected Collection $curriculumItems;
331
332
    /**
333
     * @var Collection<int, AccessUrlRelUser>
334
     */
335
    #[ORM\OneToMany(
336
        mappedBy: 'user',
337
        targetEntity: AccessUrlRelUser::class,
338
        cascade: ['persist', 'remove'],
339
        orphanRemoval: true
340
    )]
341
    protected Collection $portals;
342
343
    /**
344
     * @var Collection<int, ResourceNode>
345
     */
346
    #[ORM\OneToMany(mappedBy: 'creator', targetEntity: ResourceNode::class, cascade: ['persist', 'remove'])]
347
    protected Collection $resourceNodes;
348
349
    /**
350
     * @var Collection<int, SessionRelCourseRelUser>
351
     */
352
    #[ORM\OneToMany(
353
        mappedBy: 'user',
354
        targetEntity: SessionRelCourseRelUser::class,
355
        cascade: ['persist'],
356
        orphanRemoval: true
357
    )]
358
    protected Collection $sessionRelCourseRelUsers;
359
360
    /**
361
     * @var Collection<int, SessionRelUser>
362
     */
363
    #[ORM\OneToMany(
364
        mappedBy: 'user',
365
        targetEntity: SessionRelUser::class,
366
        cascade: ['persist', 'remove'],
367
        orphanRemoval: true
368
    )]
369
    protected Collection $sessionsRelUser;
370
371
    /**
372
     * @var Collection<int, SkillRelUser>
373
     */
374
    #[ORM\OneToMany(
375
        mappedBy: 'user',
376
        targetEntity: SkillRelUser::class,
377
        cascade: ['persist', 'remove'],
378
        orphanRemoval: true
379
    )]
380
    protected Collection $achievedSkills;
381
382
    /**
383
     * @var Collection<int, SkillRelUserComment>
384
     */
385
    #[ORM\OneToMany(
386
        mappedBy: 'feedbackGiver',
387
        targetEntity: SkillRelUserComment::class,
388
        cascade: ['persist', 'remove'],
389
        orphanRemoval: true
390
    )]
391
    protected Collection $commentedUserSkills;
392
393
    /**
394
     * @var Collection<int, GradebookCategory>
395
     */
396
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: GradebookCategory::class)]
397
    protected Collection $gradeBookCategories;
398
399
    /**
400
     * @var Collection<int, GradebookCertificate>
401
     */
402
    #[ORM\OneToMany(
403
        mappedBy: 'user',
404
        targetEntity: GradebookCertificate::class,
405
        cascade: ['persist', 'remove'],
406
        orphanRemoval: true
407
    )]
408
    protected Collection $gradeBookCertificates;
409
410
    /**
411
     * @var Collection<int, GradebookComment>
412
     */
413
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: GradebookComment::class)]
414
    protected Collection $gradeBookComments;
415
416
    /**
417
     * @var Collection<int, GradebookResult>
418
     */
419
    #[ORM\OneToMany(
420
        mappedBy: 'user',
421
        targetEntity: GradebookResult::class,
422
        cascade: ['persist', 'remove'],
423
        orphanRemoval: true
424
    )]
425
    protected Collection $gradeBookResults;
426
427
    /**
428
     * @var Collection<int, GradebookResultLog>
429
     */
430
    #[ORM\OneToMany(
431
        mappedBy: 'user',
432
        targetEntity: GradebookResultLog::class,
433
        cascade: ['persist', 'remove'],
434
        orphanRemoval: true
435
    )]
436
    protected Collection $gradeBookResultLogs;
437
438
    /**
439
     * @var Collection<int, GradebookScoreLog>
440
     */
441
    #[ORM\OneToMany(
442
        mappedBy: 'user',
443
        targetEntity: GradebookScoreLog::class,
444
        cascade: ['persist', 'remove'],
445
        orphanRemoval: true
446
    )]
447
    protected Collection $gradeBookScoreLogs;
448
449
    /**
450
     * @var Collection<int, UserRelUser>
451
     */
452
    #[ORM\OneToMany(
453
        mappedBy: 'user',
454
        targetEntity: UserRelUser::class,
455
        cascade: ['persist', 'remove'],
456
        fetch: 'EXTRA_LAZY',
457
        orphanRemoval: true
458
    )]
459
    protected Collection $friends;
460
461
    /**
462
     * @var Collection<int, UserRelUser>
463
     */
464
    #[ORM\OneToMany(
465
        mappedBy: 'friend',
466
        targetEntity: UserRelUser::class,
467
        cascade: ['persist', 'remove'],
468
        fetch: 'EXTRA_LAZY',
469
        orphanRemoval: true
470
    )]
471
    protected Collection $friendsWithMe;
472
473
    /**
474
     * @var Collection<int, GradebookLinkevalLog>
475
     */
476
    #[ORM\OneToMany(
477
        mappedBy: 'user',
478
        targetEntity: GradebookLinkevalLog::class,
479
        cascade: ['persist', 'remove'],
480
        orphanRemoval: true
481
    )]
482
    protected Collection $gradeBookLinkEvalLogs;
483
484
    /**
485
     * @var Collection<int, SequenceValue>
486
     */
487
    #[ORM\OneToMany(
488
        mappedBy: 'user',
489
        targetEntity: SequenceValue::class,
490
        cascade: ['persist', 'remove'],
491
        orphanRemoval: true
492
    )]
493
    protected Collection $sequenceValues;
494
495
    /**
496
     * @var Collection<int, TrackEExerciseConfirmation>
497
     */
498
    #[ORM\OneToMany(
499
        mappedBy: 'user',
500
        targetEntity: TrackEExerciseConfirmation::class,
501
        cascade: ['persist', 'remove'],
502
        orphanRemoval: true
503
    )]
504
    protected Collection $trackEExerciseConfirmations;
505
506
    /**
507
     * @var Collection<int, TrackEAttempt>
508
     */
509
    #[ORM\OneToMany(
510
        mappedBy: 'user',
511
        targetEntity: TrackEAccessComplete::class,
512
        cascade: [
513
            'persist',
514
            'remove',
515
        ],
516
        orphanRemoval: true
517
    )]
518
    protected Collection $trackEAccessCompleteList;
519
520
    /**
521
     * @var Collection<int, Templates>
522
     */
523
    #[ORM\OneToMany(
524
        mappedBy: 'user',
525
        targetEntity: Templates::class,
526
        cascade: ['persist', 'remove'],
527
        fetch: 'EXTRA_LAZY',
528
        orphanRemoval: true
529
    )]
530
    protected Collection $templates;
531
532
    /**
533
     * @var Collection<int, TrackEAttempt>
534
     */
535
    #[ORM\OneToMany(
536
        mappedBy: 'user',
537
        targetEntity: TrackEAttempt::class,
538
        cascade: ['persist', 'remove'],
539
        orphanRemoval: true
540
    )]
541
    protected Collection $trackEAttempts;
542
543
    /**
544
     * @var Collection<int, TrackECourseAccess>
545
     */
546
    #[ORM\OneToMany(
547
        mappedBy: 'user',
548
        targetEntity: TrackECourseAccess::class,
549
        cascade: ['persist', 'remove'],
550
        orphanRemoval: true
551
    )]
552
    protected Collection $trackECourseAccess;
553
554
    /**
555
     * @var Collection<int, UserCourseCategory>
556
     */
557
    #[ORM\OneToMany(
558
        mappedBy: 'user',
559
        targetEntity: UserCourseCategory::class,
560
        cascade: ['persist', 'remove'],
561
        orphanRemoval: true
562
    )]
563
    protected Collection $userCourseCategories;
564
565
    /**
566
     * @var Collection<int, UserRelCourseVote>
567
     */
568
    #[ORM\OneToMany(
569
        mappedBy: 'user',
570
        targetEntity: UserRelCourseVote::class,
571
        cascade: ['persist', 'remove'],
572
        orphanRemoval: true
573
    )]
574
    protected Collection $userRelCourseVotes;
575
576
    /**
577
     * @var Collection<int, UserRelTag>
578
     */
579
    #[ORM\OneToMany(
580
        mappedBy: 'user',
581
        targetEntity: UserRelTag::class,
582
        cascade: ['persist', 'remove'],
583
        orphanRemoval: true
584
    )]
585
    protected Collection $userRelTags;
586
587
    /**
588
     * @var Collection<int, CGroupRelUser>
589
     */
590
    #[ORM\OneToMany(
591
        mappedBy: 'user',
592
        targetEntity: CGroupRelUser::class,
593
        cascade: ['persist', 'remove'],
594
        orphanRemoval: true
595
    )]
596
    protected Collection $courseGroupsAsMember;
597
598
    /**
599
     * @var Collection<int, CGroupRelTutor>
600
     */
601
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: CGroupRelTutor::class, orphanRemoval: true)]
602
    protected Collection $courseGroupsAsTutor;
603
604
    #[ORM\Column(name: 'status', type: 'integer')]
605
    protected int $status;
606
607
    #[ORM\Column(name: 'official_code', type: 'string', length: 40, nullable: true)]
608
    protected ?string $officialCode = null;
609
610
    #[ORM\Column(name: 'picture_uri', type: 'string', length: 250, nullable: true)]
611
    protected ?string $pictureUri = null;
612
613
    #[ORM\Column(name: 'creator_id', type: 'integer', unique: false, nullable: true)]
614
    protected ?int $creatorId = null;
615
616
    #[ORM\Column(name: 'competences', type: 'text', unique: false, nullable: true)]
617
    protected ?string $competences = null;
618
619
    #[ORM\Column(name: 'diplomas', type: 'text', unique: false, nullable: true)]
620
    protected ?string $diplomas = null;
621
622
    #[ORM\Column(name: 'openarea', type: 'text', unique: false, nullable: true)]
623
    protected ?string $openarea = null;
624
625
    #[ORM\Column(name: 'teach', type: 'text', unique: false, nullable: true)]
626
    protected ?string $teach = null;
627
628
    #[ORM\Column(name: 'productions', type: 'string', length: 250, unique: false, nullable: true)]
629
    protected ?string $productions = null;
630
631
    #[ORM\Column(name: 'expiration_date', type: 'datetime', unique: false, nullable: true)]
632
    protected ?DateTime $expirationDate = null;
633
634
    #[Groups(['user:read', 'user_json:read'])]
635
    #[ORM\Column(name: 'active', type: 'integer')]
636
    protected int $active;
637
638
    #[ORM\Column(name: 'openid', type: 'string', length: 255, unique: false, nullable: true)]
639
    protected ?string $openid = null;
640
641
    #[ORM\Column(name: 'theme', type: 'string', length: 255, unique: false, nullable: true)]
642
    protected ?string $theme = null;
643
644
    #[ORM\Column(name: 'hr_dept_id', type: 'smallint', unique: false, nullable: true)]
645
    protected ?int $hrDeptId = null;
646
647
    #[Groups(['user:write'])]
648
    protected ?AccessUrl $currentUrl = null;
649
650
    /**
651
     * @var Collection<int, MessageTag>
652
     */
653
    #[ORM\OneToMany(
654
        mappedBy: 'user',
655
        targetEntity: MessageTag::class,
656
        cascade: ['persist', 'remove'],
657
        orphanRemoval: true
658
    )]
659
    protected Collection $messageTags;
660
661
    /**
662
     * @var Collection<int, Message>
663
     */
664
    #[ORM\OneToMany(
665
        mappedBy: 'sender',
666
        targetEntity: Message::class,
667
        cascade: ['persist']
668
    )]
669
    protected Collection $sentMessages;
670
671
    /**
672
     * @var Collection<int, MessageRelUser>
673
     */
674
    #[ORM\OneToMany(mappedBy: 'receiver', targetEntity: MessageRelUser::class, cascade: ['persist', 'remove'])]
675
    protected Collection $receivedMessages;
676
677
    /**
678
     * @var Collection<int, CSurveyInvitation>
679
     */
680
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: CSurveyInvitation::class, cascade: ['persist', 'remove'])]
681
    protected Collection $surveyInvitations;
682
683
    /**
684
     * @var Collection<int, TrackELogin>
685
     */
686
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: TrackELogin::class, cascade: ['persist', 'remove'])]
687
    protected Collection $logins;
688
689
    #[ORM\OneToOne(mappedBy: 'user', targetEntity: Admin::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
690
    protected ?Admin $admin = null;
691
692
    #[ORM\Column(type: 'uuid', unique: true)]
693
    protected Uuid $uuid;
694
695
    // Property used only during installation.
696
    protected bool $skipResourceNode = false;
697
698
    #[Groups([
699
        'user:read',
700
        'user_json:read',
701
        'social_post:read',
702
        'course:read',
703
        'course_rel_user:read',
704
        'message:read',
705
        'user_subscriptions:sessions',
706
        'student_publication_rel_user:read',
707
    ])]
708
    protected string $fullName;
709
710
    #[ORM\OneToMany(mappedBy: 'sender', targetEntity: SocialPost::class, orphanRemoval: true)]
711
    private Collection $sentSocialPosts;
712
713
    #[ORM\OneToMany(mappedBy: 'userReceiver', targetEntity: SocialPost::class)]
714
    private Collection $receivedSocialPosts;
715
716
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: SocialPostFeedback::class, orphanRemoval: true)]
717
    private Collection $socialPostsFeedbacks;
718
719
    #[ORM\Column(name: 'mfa_enabled', type: 'boolean', options: ['default' => false])]
720
    protected bool $mfaEnabled = false;
721
722
    #[ORM\Column(name: 'mfa_service', type: 'string', length: 255, nullable: true)]
723
    protected ?string $mfaService = null;
724
725
    #[ORM\Column(name: 'mfa_secret', type: 'string', length: 255, nullable: true)]
726
    protected ?string $mfaSecret = null;
727
728
    #[ORM\Column(name: 'mfa_backup_codes', type: 'text', nullable: true)]
729
    protected ?string $mfaBackupCodes = null;
730
731
    #[ORM\Column(name: 'mfa_last_used', type: 'datetime', nullable: true)]
732
    protected ?DateTimeInterface $mfaLastUsed = null;
733
734
    /**
735
     * @var Collection<int, UserAuthSource>
736
     */
737
    #[ORM\OneToMany(mappedBy: 'user', targetEntity: UserAuthSource::class, cascade: ['persist'], orphanRemoval: true)]
738
    private Collection $authSources;
739
740
    public function __construct()
741
    {
742
        $this->skipResourceNode = false;
743
        $this->uuid = Uuid::v4();
744
        $this->apiToken = null;
745
        $this->biography = '';
746
        $this->website = '';
747
        $this->locale = 'en';
748
        $this->timezone = 'Europe/Paris';
749
        $this->status = CourseRelUser::STUDENT;
750
        $this->salt = sha1(uniqid('', true));
751
        $this->active = 1;
752
        $this->locked = false;
753
        $this->expired = false;
754
        $this->courses = new ArrayCollection();
755
        $this->classes = new ArrayCollection();
756
        $this->curriculumItems = new ArrayCollection();
757
        $this->portals = new ArrayCollection();
758
        $this->dropBoxSentFiles = new ArrayCollection();
759
        $this->dropBoxReceivedFiles = new ArrayCollection();
760
        $this->groups = new ArrayCollection();
761
        $this->gradeBookCertificates = new ArrayCollection();
762
        $this->courseGroupsAsMember = new ArrayCollection();
763
        $this->courseGroupsAsTutor = new ArrayCollection();
764
        $this->resourceNodes = new ArrayCollection();
765
        $this->sessionRelCourseRelUsers = new ArrayCollection();
766
        $this->achievedSkills = new ArrayCollection();
767
        $this->commentedUserSkills = new ArrayCollection();
768
        $this->gradeBookCategories = new ArrayCollection();
769
        $this->gradeBookComments = new ArrayCollection();
770
        $this->gradeBookResults = new ArrayCollection();
771
        $this->gradeBookResultLogs = new ArrayCollection();
772
        $this->gradeBookScoreLogs = new ArrayCollection();
773
        $this->friends = new ArrayCollection();
774
        $this->friendsWithMe = new ArrayCollection();
775
        $this->gradeBookLinkEvalLogs = new ArrayCollection();
776
        $this->messageTags = new ArrayCollection();
777
        $this->sequenceValues = new ArrayCollection();
778
        $this->trackEExerciseConfirmations = new ArrayCollection();
779
        $this->trackEAccessCompleteList = new ArrayCollection();
780
        $this->templates = new ArrayCollection();
781
        $this->trackEAttempts = new ArrayCollection();
782
        $this->trackECourseAccess = new ArrayCollection();
783
        $this->userCourseCategories = new ArrayCollection();
784
        $this->userRelCourseVotes = new ArrayCollection();
785
        $this->userRelTags = new ArrayCollection();
786
        $this->sessionsRelUser = new ArrayCollection();
787
        $this->sentMessages = new ArrayCollection();
788
        $this->receivedMessages = new ArrayCollection();
789
        $this->surveyInvitations = new ArrayCollection();
790
        $this->logins = new ArrayCollection();
791
        $this->createdAt = new DateTime();
792
        $this->updatedAt = new DateTime();
793
        $this->roles = [];
794
        $this->credentialsExpired = false;
795
        $this->credentialsExpireAt = new DateTime();
796
        $this->dateOfBirth = new DateTime();
797
        $this->expiresAt = new DateTime();
798
        $this->passwordRequestedAt = new DateTime();
799
        $this->sentSocialPosts = new ArrayCollection();
800
        $this->receivedSocialPosts = new ArrayCollection();
801
        $this->socialPostsFeedbacks = new ArrayCollection();
802
        $this->authSources = new ArrayCollection();
803
    }
804
805
    public function __toString(): string
806
    {
807
        return $this->username;
808
    }
809
810
    public static function getPasswordConstraints(): array
811
    {
812
        return [
813
            new Assert\Length(['min' => 5]),
814
            new Assert\Regex(['pattern' => '/^[a-z\-_0-9]+$/i', 'htmlPattern' => '/^[a-z\-_0-9]+$/i']),
815
            new Assert\Regex(['pattern' => '/[0-9]{2}/', 'htmlPattern' => '/[0-9]{2}/']),
816
        ];
817
    }
818
819
    public static function loadValidatorMetadata(ClassMetadata $metadata): void {}
820
821
    public function getUuid(): Uuid
822
    {
823
        return $this->uuid;
824
    }
825
826
    public function setUuid(Uuid $uuid): self
827
    {
828
        $this->uuid = $uuid;
829
830
        return $this;
831
    }
832
833
    public function getResourceNode(): ?ResourceNode
834
    {
835
        return $this->resourceNode;
836
    }
837
838
    public function setResourceNode(ResourceNode $resourceNode): self
839
    {
840
        $this->resourceNode = $resourceNode;
841
842
        return $this;
843
    }
844
845
    public function hasResourceNode(): bool
846
    {
847
        return $this->resourceNode instanceof ResourceNode;
848
    }
849
850
    public function getResourceNodes(): Collection
851
    {
852
        return $this->resourceNodes;
853
    }
854
855
    public function addResourceNode(ResourceNode $resourceNode): static
856
    {
857
        if (!$this->resourceNodes->contains($resourceNode)) {
858
            $this->resourceNodes->add($resourceNode);
859
            $resourceNode->setCreator($this);
860
        }
861
862
        return $this;
863
    }
864
865
    public function getDropBoxSentFiles(): Collection
866
    {
867
        return $this->dropBoxSentFiles;
868
    }
869
870
    public function setDropBoxSentFiles(Collection $value): self
871
    {
872
        $this->dropBoxSentFiles = $value;
873
874
        return $this;
875
    }
876
877
    public function getCourses(): Collection
878
    {
879
        return $this->courses;
880
    }
881
882
    /**
883
     * @param Collection<int, CourseRelUser> $courses
884
     */
885
    public function setCourses(Collection $courses): self
886
    {
887
        $this->courses = $courses;
888
889
        return $this;
890
    }
891
892
    public function setPortal(AccessUrlRelUser $portal): self
893
    {
894
        $this->portals->add($portal);
895
896
        return $this;
897
    }
898
899
    /**
900
     * Get a bool on whether the user is active or not. Active can be "-1" which means pre-deleted, and is returned as false (not active).
901
     *
902
     * @return bool True if active = 1, false in any other case (0 = inactive, -1 = predeleted)
903
     */
904
    public function getIsActive(): bool
905
    {
906
        return 1 === $this->active;
907
    }
908
909
    public function isEnabled(): bool
910
    {
911
        return $this->isActive();
912
    }
913
914
    /**
915
     * Returns the list of classes for the user.
916
     */
917
    public function getCompleteNameWithClasses(): string
918
    {
919
        $classSubscription = $this->getClasses();
920
        $classList = [];
921
922
        /** @var UsergroupRelUser $subscription */
923
        foreach ($classSubscription as $subscription) {
924
            $class = $subscription->getUsergroup();
925
            $classList[] = $class->getTitle();
926
        }
927
        $classString = empty($classList) ? null : ' ['.implode(', ', $classList).']';
928
929
        return UserManager::formatUserFullName($this).$classString;
930
    }
931
932
    public function getClasses(): Collection
933
    {
934
        return $this->classes;
935
    }
936
937
    /**
938
     * @param Collection<int, UsergroupRelUser> $classes
939
     */
940
    public function setClasses(Collection $classes): self
941
    {
942
        $this->classes = $classes;
943
944
        return $this;
945
    }
946
947
    public function getEmail(): string
948
    {
949
        return $this->email;
950
    }
951
952
    public function setEmail(string $email): self
953
    {
954
        $this->email = $email;
955
956
        return $this;
957
    }
958
959
    public function getOfficialCode(): ?string
960
    {
961
        return $this->officialCode;
962
    }
963
964
    public function setOfficialCode(?string $officialCode): self
965
    {
966
        $this->officialCode = $officialCode;
967
968
        return $this;
969
    }
970
971
    public function getPhone(): ?string
972
    {
973
        return $this->phone;
974
    }
975
976
    public function setPhone(?string $phone): self
977
    {
978
        $this->phone = $phone;
979
980
        return $this;
981
    }
982
983
    public function getAddress(): ?string
984
    {
985
        return $this->address;
986
    }
987
988
    public function setAddress(?string $address): self
989
    {
990
        $this->address = $address;
991
992
        return $this;
993
    }
994
995
    public function getCreatorId(): ?int
996
    {
997
        return $this->creatorId;
998
    }
999
1000
    public function setCreatorId(int $creatorId): self
1001
    {
1002
        $this->creatorId = $creatorId;
1003
1004
        return $this;
1005
    }
1006
1007
    public function getCompetences(): ?string
1008
    {
1009
        return $this->competences;
1010
    }
1011
1012
    public function setCompetences(?string $competences): self
1013
    {
1014
        $this->competences = $competences;
1015
1016
        return $this;
1017
    }
1018
1019
    public function getDiplomas(): ?string
1020
    {
1021
        return $this->diplomas;
1022
    }
1023
1024
    public function setDiplomas(?string $diplomas): self
1025
    {
1026
        $this->diplomas = $diplomas;
1027
1028
        return $this;
1029
    }
1030
1031
    public function getOpenarea(): ?string
1032
    {
1033
        return $this->openarea;
1034
    }
1035
1036
    public function setOpenarea(?string $openarea): self
1037
    {
1038
        $this->openarea = $openarea;
1039
1040
        return $this;
1041
    }
1042
1043
    public function getTeach(): ?string
1044
    {
1045
        return $this->teach;
1046
    }
1047
1048
    public function setTeach(?string $teach): self
1049
    {
1050
        $this->teach = $teach;
1051
1052
        return $this;
1053
    }
1054
1055
    public function getProductions(): ?string
1056
    {
1057
        return $this->productions;
1058
    }
1059
1060
    public function setProductions(?string $productions): self
1061
    {
1062
        $this->productions = $productions;
1063
1064
        return $this;
1065
    }
1066
1067
    public function getExpirationDate(): ?DateTime
1068
    {
1069
        return $this->expirationDate;
1070
    }
1071
1072
    public function setExpirationDate(?DateTime $expirationDate): self
1073
    {
1074
        $this->expirationDate = $expirationDate;
1075
1076
        return $this;
1077
    }
1078
1079
    public function getActive(): int
1080
    {
1081
        return $this->active;
1082
    }
1083
1084
    public function isActive(): bool
1085
    {
1086
        return $this->getIsActive();
1087
    }
1088
1089
    public function setActive(int $active): self
1090
    {
1091
        $this->active = $active;
1092
1093
        return $this;
1094
    }
1095
1096
    public function getOpenid(): ?string
1097
    {
1098
        return $this->openid;
1099
    }
1100
1101
    public function setOpenid(string $openid): self
1102
    {
1103
        $this->openid = $openid;
1104
1105
        return $this;
1106
    }
1107
1108
    public function getTheme(): ?string
1109
    {
1110
        return $this->theme;
1111
    }
1112
1113
    public function setTheme(string $theme): self
1114
    {
1115
        $this->theme = $theme;
1116
1117
        return $this;
1118
    }
1119
1120
    public function getHrDeptId(): ?int
1121
    {
1122
        return $this->hrDeptId;
1123
    }
1124
1125
    public function setHrDeptId(int $hrDeptId): self
1126
    {
1127
        $this->hrDeptId = $hrDeptId;
1128
1129
        return $this;
1130
    }
1131
1132
    public function isOnline(): bool
1133
    {
1134
        return false;
1135
    }
1136
1137
    public function getIdentifier(): int
1138
    {
1139
        return $this->getId();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getId() could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
1140
    }
1141
1142
    public function getId(): ?int
1143
    {
1144
        return $this->id;
1145
    }
1146
1147
    public function getIri(): ?string
1148
    {
1149
        if (null === $this->id) {
1150
            return null;
1151
        }
1152
1153
        return '/api/users/'.$this->getId();
1154
    }
1155
1156
    public function getSlug(): string
1157
    {
1158
        return $this->getUsername();
1159
    }
1160
1161
    public function getUsername(): string
1162
    {
1163
        return $this->username;
1164
    }
1165
1166
    public function setUsername(string $username): self
1167
    {
1168
        $this->username = $username;
1169
1170
        return $this;
1171
    }
1172
1173
    public function setSlug(string $slug): self
1174
    {
1175
        return $this->setUsername($slug);
1176
    }
1177
1178
    public function getLastLogin(): ?DateTime
1179
    {
1180
        return $this->lastLogin;
1181
    }
1182
1183
    public function setLastLogin(?DateTime $lastLogin = null): self
1184
    {
1185
        $this->lastLogin = $lastLogin;
1186
1187
        return $this;
1188
    }
1189
1190
    public function getConfirmationToken(): ?string
1191
    {
1192
        return $this->confirmationToken;
1193
    }
1194
1195
    public function setConfirmationToken(string $confirmationToken): self
1196
    {
1197
        $this->confirmationToken = $confirmationToken;
1198
1199
        return $this;
1200
    }
1201
1202
    public function isPasswordRequestNonExpired(int $ttl): bool
1203
    {
1204
        return $this->getPasswordRequestedAt() instanceof DateTime && $this->getPasswordRequestedAt()->getTimestamp(
1205
        ) + $ttl > time();
1206
    }
1207
1208
    public function getPasswordRequestedAt(): ?DateTime
1209
    {
1210
        return $this->passwordRequestedAt;
1211
    }
1212
1213
    public function setPasswordRequestedAt(?DateTime $date = null): self
1214
    {
1215
        $this->passwordRequestedAt = $date;
1216
1217
        return $this;
1218
    }
1219
1220
    public function getPlainPassword(): ?string
1221
    {
1222
        return $this->plainPassword;
1223
    }
1224
1225
    public function setPlainPassword(?string $password): self
1226
    {
1227
        $this->plainPassword = $password;
1228
        // forces the object to look "dirty" to Doctrine. Avoids
1229
        // Doctrine *not* saving this entity, if only plainPassword changes
1230
        $this->password = '';
1231
1232
        return $this;
1233
    }
1234
1235
    /**
1236
     * Returns the expiration date.
1237
     */
1238
    public function getExpiresAt(): ?DateTime
1239
    {
1240
        return $this->expiresAt;
1241
    }
1242
1243
    public function setExpiresAt(DateTime $date): self
1244
    {
1245
        $this->expiresAt = $date;
1246
1247
        return $this;
1248
    }
1249
1250
    /**
1251
     * Returns the credentials expiration date.
1252
     */
1253
    public function getCredentialsExpireAt(): ?DateTime
1254
    {
1255
        return $this->credentialsExpireAt;
1256
    }
1257
1258
    /**
1259
     * Sets the credentials expiration date.
1260
     */
1261
    public function setCredentialsExpireAt(?DateTime $date = null): self
1262
    {
1263
        $this->credentialsExpireAt = $date;
1264
1265
        return $this;
1266
    }
1267
1268
    #[Groups(['user:read', 'student_publication:read', 'student_publication_comment:read'])]
1269
    public function getFullname(): string
1270
    {
1271
        if (empty($this->fullName)) {
1272
            return \sprintf('%s %s', $this->getFirstname(), $this->getLastname());
1273
        }
1274
1275
        return $this->fullName;
1276
    }
1277
1278
    public function setFullName(string $fullName): self
1279
    {
1280
        $this->fullName = $fullName;
1281
1282
        return $this;
1283
    }
1284
1285
    public function getFirstname(): ?string
1286
    {
1287
        return $this->firstname;
1288
    }
1289
1290
    public function setFirstname(string $firstname): self
1291
    {
1292
        $this->firstname = $firstname;
1293
1294
        return $this;
1295
    }
1296
1297
    public function getLastname(): ?string
1298
    {
1299
        return $this->lastname;
1300
    }
1301
1302
    public function setLastname(string $lastname): self
1303
    {
1304
        $this->lastname = $lastname;
1305
1306
        return $this;
1307
    }
1308
1309
    public function hasGroup(string $name): bool
1310
    {
1311
        return \in_array($name, $this->getGroupNames(), true);
1312
    }
1313
1314
    public function getGroupNames(): array
1315
    {
1316
        $names = [];
1317
        foreach ($this->getGroups() as $group) {
1318
            $names[] = $group->getTitle();
1319
        }
1320
1321
        return $names;
1322
    }
1323
1324
    public function getGroups(): Collection
1325
    {
1326
        return $this->groups;
1327
    }
1328
1329
    /**
1330
     * Sets the user groups.
1331
     */
1332
    public function setGroups(Collection $groups): self
1333
    {
1334
        foreach ($groups as $group) {
1335
            $this->addGroup($group);
1336
        }
1337
1338
        return $this;
1339
    }
1340
1341
    public function addGroup(Group $group): self
1342
    {
1343
        if (!$this->getGroups()->contains($group)) {
1344
            $this->getGroups()->add($group);
1345
        }
1346
1347
        return $this;
1348
    }
1349
1350
    public function removeGroup(Group $group): self
1351
    {
1352
        if ($this->getGroups()->contains($group)) {
1353
            $this->getGroups()->removeElement($group);
1354
        }
1355
1356
        return $this;
1357
    }
1358
1359
    public function isAccountNonExpired(): bool
1360
    {
1361
        return true;
1362
    }
1363
1364
    public function isAccountNonLocked(): bool
1365
    {
1366
        return true;
1367
    }
1368
1369
    public function isCredentialsNonExpired(): bool
1370
    {
1371
        return true;
1372
    }
1373
1374
    public function getCredentialsExpired(): bool
1375
    {
1376
        return $this->credentialsExpired;
1377
    }
1378
1379
    public function setCredentialsExpired(bool $boolean): self
1380
    {
1381
        $this->credentialsExpired = $boolean;
1382
1383
        return $this;
1384
    }
1385
1386
    public function getExpired(): bool
1387
    {
1388
        return $this->expired;
1389
    }
1390
1391
    /**
1392
     * Sets this user to expired.
1393
     */
1394
    public function setExpired(bool $boolean): self
1395
    {
1396
        $this->expired = $boolean;
1397
1398
        return $this;
1399
    }
1400
1401
    public function getLocked(): bool
1402
    {
1403
        return $this->locked;
1404
    }
1405
1406
    public function setLocked(bool $boolean): self
1407
    {
1408
        $this->locked = $boolean;
1409
1410
        return $this;
1411
    }
1412
1413
    /**
1414
     * Check if the user has the skill.
1415
     *
1416
     * @param Skill $skill The skill
1417
     */
1418
    public function hasSkill(Skill $skill): bool
1419
    {
1420
        $achievedSkills = $this->getAchievedSkills();
1421
        foreach ($achievedSkills as $userSkill) {
1422
            if ($userSkill->getSkill()->getId() !== $skill->getId()) {
1423
                continue;
1424
            }
1425
1426
            return true;
1427
        }
1428
1429
        return false;
1430
    }
1431
1432
    /**
1433
     * @return Collection<int, SkillRelUser>
1434
     */
1435
    public function getAchievedSkills(): Collection
1436
    {
1437
        return $this->achievedSkills;
1438
    }
1439
1440
    /**
1441
     * @param Collection<int, SkillRelUser> $value
1442
     */
1443
    public function setAchievedSkills(Collection $value): self
1444
    {
1445
        $this->achievedSkills = $value;
1446
1447
        return $this;
1448
    }
1449
1450
    public function isProfileCompleted(): ?bool
1451
    {
1452
        return $this->profileCompleted;
1453
    }
1454
1455
    public function setProfileCompleted(?bool $profileCompleted): self
1456
    {
1457
        $this->profileCompleted = $profileCompleted;
1458
1459
        return $this;
1460
    }
1461
1462
    public function getCurrentUrl(): ?AccessUrl
1463
    {
1464
        return $this->currentUrl;
1465
    }
1466
1467
    public function setCurrentUrl(AccessUrl $url): self
1468
    {
1469
        $accessUrlRelUser = (new AccessUrlRelUser())->setUrl($url)->setUser($this);
1470
        $this->getPortals()->add($accessUrlRelUser);
1471
1472
        return $this;
1473
    }
1474
1475
    public function getPortals(): Collection
1476
    {
1477
        return $this->portals;
1478
    }
1479
1480
    /**
1481
     * @param Collection<int, AccessUrlRelUser> $value
1482
     */
1483
    public function setPortals(Collection $value): void
1484
    {
1485
        $this->portals = $value;
1486
    }
1487
1488
    public function getSessionsAsGeneralCoach(): array
1489
    {
1490
        return $this->getSessions(Session::GENERAL_COACH);
1491
    }
1492
1493
    /**
1494
     * Retrieves this user's related sessions.
1495
     */
1496
    public function getSessions(int $relationType): array
1497
    {
1498
        $sessions = [];
1499
        foreach ($this->getSessionsRelUser() as $sessionRelUser) {
1500
            if ($sessionRelUser->getRelationType() === $relationType) {
1501
                $sessions[] = $sessionRelUser->getSession();
1502
            }
1503
        }
1504
1505
        return $sessions;
1506
    }
1507
1508
    /**
1509
     * @return Collection<int, SessionRelUser>
1510
     */
1511
    public function getSessionsRelUser(): Collection
1512
    {
1513
        return $this->sessionsRelUser;
1514
    }
1515
1516
    public function getSessionsAsAdmin(): array
1517
    {
1518
        return $this->getSessions(Session::SESSION_ADMIN);
1519
    }
1520
1521
    public function getCommentedUserSkills(): Collection
1522
    {
1523
        return $this->commentedUserSkills;
1524
    }
1525
1526
    /**
1527
     * @param Collection<int, SkillRelUserComment> $commentedUserSkills
1528
     */
1529
    public function setCommentedUserSkills(Collection $commentedUserSkills): self
1530
    {
1531
        $this->commentedUserSkills = $commentedUserSkills;
1532
1533
        return $this;
1534
    }
1535
1536
    public function isEqualTo(UserInterface $user): bool
1537
    {
1538
        if ($this->password !== $user->getPassword()) {
1539
            return false;
1540
        }
1541
        if ($this->salt !== $user->getSalt()) {
1542
            return false;
1543
        }
1544
        if ($this->username !== $user->getUserIdentifier()) {
1545
            return false;
1546
        }
1547
1548
        return true;
1549
    }
1550
1551
    public function getPassword(): ?string
1552
    {
1553
        return $this->password;
1554
    }
1555
1556
    public function setPassword(string $password): self
1557
    {
1558
        $this->password = $password;
1559
1560
        return $this;
1561
    }
1562
1563
    public function getSalt(): ?string
1564
    {
1565
        return $this->salt;
1566
    }
1567
1568
    public function setSalt(string $salt): self
1569
    {
1570
        $this->salt = $salt;
1571
1572
        return $this;
1573
    }
1574
1575
    public function getUserIdentifier(): string
1576
    {
1577
        return $this->username;
1578
    }
1579
1580
    /**
1581
     * @return Collection<int, Message>
1582
     */
1583
    public function getSentMessages(): Collection
1584
    {
1585
        return $this->sentMessages;
1586
    }
1587
1588
    public function getReceivedMessages(): Collection
1589
    {
1590
        return $this->receivedMessages;
1591
    }
1592
1593
    public function getCourseGroupsAsMember(): Collection
1594
    {
1595
        return $this->courseGroupsAsMember;
1596
    }
1597
1598
    public function getCourseGroupsAsTutor(): Collection
1599
    {
1600
        return $this->courseGroupsAsTutor;
1601
    }
1602
1603
    public function getCourseGroupsAsMemberFromCourse(Course $course): Collection
1604
    {
1605
        $criteria = Criteria::create();
1606
        $criteria->where(Criteria::expr()->eq('cId', $course));
1607
1608
        return $this->courseGroupsAsMember->matching($criteria);
1609
    }
1610
1611
    public function eraseCredentials(): void
1612
    {
1613
        $this->plainPassword = null;
1614
    }
1615
1616
    /**
1617
     * Returns whether a user can be admin of all multi-URL portals in the case of a multi-URL install.
1618
     */
1619
    public function isSuperAdmin(): bool
1620
    {
1621
        return $this->hasRole('ROLE_SUPER_ADMIN');
1622
    }
1623
1624
    public function hasRole(string $role): bool
1625
    {
1626
        return \in_array(strtoupper($role), $this->getRoles(), true);
1627
    }
1628
1629
    /**
1630
     * Returns the user roles.
1631
     */
1632
    public function getRoles(): array
1633
    {
1634
        $roles = $this->roles;
1635
        foreach ($this->getGroups() as $group) {
1636
            $roles = array_merge($roles, $group->getRoles());
1637
        }
1638
        // we need to make sure to have at least one role
1639
        $roles[] = 'ROLE_USER';
1640
1641
        return array_unique($roles);
1642
    }
1643
1644
    public function setRoles(array $roles): self
1645
    {
1646
        $this->roles = [];
1647
        foreach ($roles as $role) {
1648
            $this->addRole($role);
1649
        }
1650
1651
        return $this;
1652
    }
1653
1654
    public function setRoleFromStatus(int $status): void
1655
    {
1656
        $role = self::getRoleFromStatus($status);
1657
        $this->addRole($role);
1658
    }
1659
1660
    public static function getRoleFromStatus(int $status): string
1661
    {
1662
        return match ($status) {
1663
            COURSEMANAGER => 'ROLE_TEACHER',
1664
            STUDENT => 'ROLE_STUDENT',
1665
            DRH => 'ROLE_HR',
1666
            SESSIONADMIN => 'ROLE_SESSION_MANAGER',
1667
            STUDENT_BOSS => 'ROLE_STUDENT_BOSS',
1668
            INVITEE => 'ROLE_INVITEE',
1669
            default => 'ROLE_USER',
1670
        };
1671
    }
1672
1673
    public function addRole(string $role): self
1674
    {
1675
        $role = strtoupper($role);
1676
        if ($role === static::ROLE_DEFAULT || empty($role)) {
1677
            return $this;
1678
        }
1679
        if (!\in_array($role, $this->roles, true)) {
1680
            $this->roles[] = $role;
1681
        }
1682
1683
        return $this;
1684
    }
1685
1686
    public function removeRole(string $role): self
1687
    {
1688
        if (false !== ($key = array_search(strtoupper($role), $this->roles, true))) {
1689
            unset($this->roles[$key]);
1690
            $this->roles = array_values($this->roles);
1691
        }
1692
1693
        return $this;
1694
    }
1695
1696
    public function getUsernameCanonical(): string
1697
    {
1698
        return $this->usernameCanonical;
1699
    }
1700
1701
    public function setUsernameCanonical(string $usernameCanonical): self
1702
    {
1703
        $this->usernameCanonical = $usernameCanonical;
1704
1705
        return $this;
1706
    }
1707
1708
    public function getEmailCanonical(): string
1709
    {
1710
        return $this->emailCanonical;
1711
    }
1712
1713
    public function setEmailCanonical(string $emailCanonical): self
1714
    {
1715
        $this->emailCanonical = $emailCanonical;
1716
1717
        return $this;
1718
    }
1719
1720
    public function getTimezone(): string
1721
    {
1722
        return $this->timezone;
1723
    }
1724
1725
    public function setTimezone(string $timezone): self
1726
    {
1727
        $this->timezone = $timezone;
1728
1729
        return $this;
1730
    }
1731
1732
    public function getLocale(): string
1733
    {
1734
        return $this->locale;
1735
    }
1736
1737
    public function setLocale(string $locale): self
1738
    {
1739
        $this->locale = $locale;
1740
1741
        return $this;
1742
    }
1743
1744
    public function getApiToken(): ?string
1745
    {
1746
        return $this->apiToken;
1747
    }
1748
1749
    public function setApiToken(string $apiToken): self
1750
    {
1751
        $this->apiToken = $apiToken;
1752
1753
        return $this;
1754
    }
1755
1756
    public function getWebsite(): ?string
1757
    {
1758
        return $this->website;
1759
    }
1760
1761
    public function setWebsite(string $website): self
1762
    {
1763
        $this->website = $website;
1764
1765
        return $this;
1766
    }
1767
1768
    public function getBiography(): ?string
1769
    {
1770
        return $this->biography;
1771
    }
1772
1773
    public function setBiography(string $biography): self
1774
    {
1775
        $this->biography = $biography;
1776
1777
        return $this;
1778
    }
1779
1780
    public function getDateOfBirth(): ?DateTime
1781
    {
1782
        return $this->dateOfBirth;
1783
    }
1784
1785
    public function setDateOfBirth(?DateTime $dateOfBirth = null): self
1786
    {
1787
        $this->dateOfBirth = $dateOfBirth;
1788
1789
        return $this;
1790
    }
1791
1792
    public function getProfileUrl(): string
1793
    {
1794
        return '/main/social/profile.php?u='.$this->id;
1795
    }
1796
1797
    public function getIconStatus(): string
1798
    {
1799
        $hasCertificates = $this->getGradeBookCertificates()->count() > 0;
1800
        $urlImg = '/img/';
1801
        if ($this->isStudent()) {
1802
            $iconStatus = $urlImg.'icons/svg/identifier_student.svg';
1803
            if ($hasCertificates) {
1804
                $iconStatus = $urlImg.'icons/svg/identifier_graduated.svg';
1805
            }
1806
1807
            return $iconStatus;
1808
        }
1809
        if ($this->isTeacher()) {
1810
            $iconStatus = $urlImg.'icons/svg/identifier_teacher.svg';
1811
            if ($this->isAdmin()) {
1812
                $iconStatus = $urlImg.'icons/svg/identifier_admin.svg';
1813
            }
1814
1815
            return $iconStatus;
1816
        }
1817
        if ($this->isStudentBoss()) {
1818
            return $urlImg.'icons/svg/identifier_teacher.svg';
1819
        }
1820
1821
        return '';
1822
    }
1823
1824
    public function getGradeBookCertificates(): Collection
1825
    {
1826
        return $this->gradeBookCertificates;
1827
    }
1828
1829
    /**
1830
     * @param Collection<int, GradebookCertificate> $gradeBookCertificates
1831
     */
1832
    public function setGradeBookCertificates(Collection $gradeBookCertificates): self
1833
    {
1834
        $this->gradeBookCertificates = $gradeBookCertificates;
1835
1836
        return $this;
1837
    }
1838
1839
    public function isStudent(): bool
1840
    {
1841
        return $this->hasRole('ROLE_STUDENT');
1842
    }
1843
1844
    public function isTeacher(): bool
1845
    {
1846
        return $this->hasRole('ROLE_TEACHER');
1847
    }
1848
1849
    public function isAdmin(): bool
1850
    {
1851
        return $this->hasRole('ROLE_ADMIN');
1852
    }
1853
1854
    public function isStudentBoss(): bool
1855
    {
1856
        return $this->hasRole('ROLE_STUDENT_BOSS');
1857
    }
1858
1859
    public function isSessionAdmin(): bool
1860
    {
1861
        return $this->hasRole('ROLE_SESSION_MANAGER');
1862
    }
1863
1864
    public function isInvitee(): bool
1865
    {
1866
        return $this->hasRole('ROLE_INVITEE');
1867
    }
1868
1869
    public function isHRM(): bool
1870
    {
1871
        return $this->hasRole('ROLE_HR');
1872
    }
1873
1874
    public function getStatus(): int
1875
    {
1876
        return $this->status;
1877
    }
1878
1879
    public function setStatus(int $status): self
1880
    {
1881
        $this->status = $status;
1882
1883
        return $this;
1884
    }
1885
1886
    public function getPictureUri(): ?string
1887
    {
1888
        return $this->pictureUri;
1889
    }
1890
1891
    /**
1892
     * @return Collection<int, GradebookCategory>
1893
     */
1894
    public function getGradeBookCategories(): Collection
1895
    {
1896
        return $this->gradeBookCategories;
1897
    }
1898
1899
    /**
1900
     * @return Collection<int, GradebookComment>
1901
     */
1902
    public function getGradeBookComments(): Collection
1903
    {
1904
        return $this->gradeBookComments;
1905
    }
1906
1907
    /**
1908
     * @return Collection<int, GradebookResult>
1909
     */
1910
    public function getGradeBookResults(): Collection
1911
    {
1912
        return $this->gradeBookResults;
1913
    }
1914
1915
    /**
1916
     * @return Collection<int, GradebookResultLog>
1917
     */
1918
    public function getGradeBookResultLogs(): Collection
1919
    {
1920
        return $this->gradeBookResultLogs;
1921
    }
1922
1923
    /**
1924
     * @return Collection<int, GradebookScoreLog>
1925
     */
1926
    public function getGradeBookScoreLogs(): Collection
1927
    {
1928
        return $this->gradeBookScoreLogs;
1929
    }
1930
1931
    /**
1932
     * @return Collection<int, GradebookLinkevalLog>
1933
     */
1934
    public function getGradeBookLinkEvalLogs(): Collection
1935
    {
1936
        return $this->gradeBookLinkEvalLogs;
1937
    }
1938
1939
    /**
1940
     * @return Collection<int, UserRelCourseVote>
1941
     */
1942
    public function getUserRelCourseVotes(): Collection
1943
    {
1944
        return $this->userRelCourseVotes;
1945
    }
1946
1947
    /**
1948
     * @return Collection<int, UserRelTag>
1949
     */
1950
    public function getUserRelTags(): Collection
1951
    {
1952
        return $this->userRelTags;
1953
    }
1954
1955
    public function getCurriculumItems(): Collection
1956
    {
1957
        return $this->curriculumItems;
1958
    }
1959
1960
    /**
1961
     * @return Collection<int, UserRelUser>
1962
     */
1963
    public function getFriends(): Collection
1964
    {
1965
        return $this->friends;
1966
    }
1967
1968
    /**
1969
     * @return Collection<int, UserRelUser>
1970
     */
1971
    public function getFriendsWithMe(): Collection
1972
    {
1973
        return $this->friendsWithMe;
1974
    }
1975
1976
    public function addFriend(self $friend): self
1977
    {
1978
        return $this->addUserRelUser($friend, UserRelUser::USER_RELATION_TYPE_FRIEND);
1979
    }
1980
1981
    public function addUserRelUser(self $friend, int $relationType): self
1982
    {
1983
        $userRelUser = (new UserRelUser())->setUser($this)->setFriend($friend)->setRelationType($relationType);
1984
        $this->friends->add($userRelUser);
1985
1986
        return $this;
1987
    }
1988
1989
    /**
1990
     * @return Collection<int, Templates>
1991
     */
1992
    public function getTemplates(): Collection
1993
    {
1994
        return $this->templates;
1995
    }
1996
1997
    public function getDropBoxReceivedFiles(): Collection
1998
    {
1999
        return $this->dropBoxReceivedFiles;
2000
    }
2001
2002
    /**
2003
     * @return Collection<int, SequenceValue>
2004
     */
2005
    public function getSequenceValues(): Collection
2006
    {
2007
        return $this->sequenceValues;
2008
    }
2009
2010
    /**
2011
     * @return Collection<int, TrackEExerciseConfirmation>
2012
     */
2013
    public function getTrackEExerciseConfirmations(): Collection
2014
    {
2015
        return $this->trackEExerciseConfirmations;
2016
    }
2017
2018
    /**
2019
     * @return Collection<int, TrackEAttempt>
2020
     */
2021
    public function getTrackEAccessCompleteList(): Collection
2022
    {
2023
        return $this->trackEAccessCompleteList;
2024
    }
2025
2026
    /**
2027
     * @return Collection<int, TrackEAttempt>
2028
     */
2029
    public function getTrackEAttempts(): Collection
2030
    {
2031
        return $this->trackEAttempts;
2032
    }
2033
2034
    /**
2035
     * @return Collection<int, TrackECourseAccess>
2036
     */
2037
    public function getTrackECourseAccess(): Collection
2038
    {
2039
        return $this->trackECourseAccess;
2040
    }
2041
2042
    /**
2043
     * @return Collection<int, UserCourseCategory>
2044
     */
2045
    public function getUserCourseCategories(): Collection
2046
    {
2047
        return $this->userCourseCategories;
2048
    }
2049
2050
    public function getCourseGroupsAsTutorFromCourse(Course $course): Collection
2051
    {
2052
        $criteria = Criteria::create();
2053
        $criteria->where(Criteria::expr()->eq('cId', $course->getId()));
2054
2055
        return $this->courseGroupsAsTutor->matching($criteria);
2056
    }
2057
2058
    /**
2059
     * Retrieves this user's related student sessions.
2060
     *
2061
     * @return Session[]
2062
     */
2063
    public function getSessionsAsStudent(): array
2064
    {
2065
        return $this->getSessions(Session::STUDENT);
2066
    }
2067
2068
    public function addSessionRelUser(SessionRelUser $sessionSubscription): static
2069
    {
2070
        $this->sessionsRelUser->add($sessionSubscription);
2071
2072
        return $this;
2073
    }
2074
2075
    public function isSkipResourceNode(): bool
2076
    {
2077
        return $this->skipResourceNode;
2078
    }
2079
2080
    public function setSkipResourceNode(bool $skipResourceNode): self
2081
    {
2082
        $this->skipResourceNode = $skipResourceNode;
2083
2084
        return $this;
2085
    }
2086
2087
    /**
2088
     * Retrieves this user's related DRH sessions.
2089
     *
2090
     * @return Session[]
2091
     */
2092
    public function getDRHSessions(): array
2093
    {
2094
        return $this->getSessions(Session::DRH);
2095
    }
2096
2097
    /**
2098
     * Get this user's related accessible sessions of a type, student by default.
2099
     *
2100
     * @return Session[]
2101
     */
2102
    public function getCurrentlyAccessibleSessions(int $relationType = Session::STUDENT): array
2103
    {
2104
        $sessions = [];
2105
        foreach ($this->getSessions($relationType) as $session) {
2106
            if ($session->isCurrentlyAccessible()) {
2107
                $sessions[] = $session;
2108
            }
2109
        }
2110
2111
        return $sessions;
2112
    }
2113
2114
    public function getResourceIdentifier(): int
2115
    {
2116
        return $this->id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->id could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
2117
    }
2118
2119
    public function getResourceName(): string
2120
    {
2121
        return $this->getUsername();
2122
    }
2123
2124
    public function setResourceName(string $name): void
2125
    {
2126
        $this->setUsername($name);
2127
    }
2128
2129
    public function setParent(AbstractResource $parent): void {}
2130
2131
    public function getDefaultIllustration(int $size): string
2132
    {
2133
        $size = empty($size) ? 32 : $size;
2134
2135
        return \sprintf('/img/icons/%s/unknown.png', $size);
2136
    }
2137
2138
    public function getAdmin(): ?Admin
2139
    {
2140
        return $this->admin;
2141
    }
2142
2143
    public function setAdmin(?Admin $admin): self
2144
    {
2145
        $this->admin = $admin;
2146
2147
        return $this;
2148
    }
2149
2150
    public function addUserAsAdmin(): self
2151
    {
2152
        if (null === $this->admin) {
2153
            $admin = new Admin();
2154
            $admin->setUser($this);
2155
            $this->setAdmin($admin);
2156
            $this->addRole('ROLE_ADMIN');
2157
        }
2158
2159
        return $this;
2160
    }
2161
2162
    public function removeUserAsAdmin(): self
2163
    {
2164
        $this->admin->setUser(null);
0 ignored issues
show
Bug introduced by
The method setUser() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2164
        $this->admin->/** @scrutinizer ignore-call */ 
2165
                      setUser(null);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
2165
        $this->admin = null;
2166
        $this->removeRole('ROLE_ADMIN');
2167
2168
        return $this;
2169
    }
2170
2171
    public function getSessionsByStatusInCourseSubscription(int $status): ReadableCollection
2172
    {
2173
        $criteria = Criteria::create()->where(Criteria::expr()->eq('status', $status));
2174
2175
        /** @var ArrayCollection $subscriptions */
2176
        $subscriptions = $this->getSessionRelCourseRelUsers();
2177
2178
        return $subscriptions->matching($criteria)->map(
2179
            fn (SessionRelCourseRelUser $sessionRelCourseRelUser) => $sessionRelCourseRelUser->getSession()
2180
        );
2181
    }
2182
2183
    /**
2184
     * @return Collection<int, SessionRelCourseRelUser>
2185
     */
2186
    public function getSessionRelCourseRelUsers(): Collection
2187
    {
2188
        return $this->sessionRelCourseRelUsers;
2189
    }
2190
2191
    /**
2192
     * @param Collection<int, SessionRelCourseRelUser> $sessionRelCourseRelUsers
2193
     */
2194
    public function setSessionRelCourseRelUsers(Collection $sessionRelCourseRelUsers): self
2195
    {
2196
        $this->sessionRelCourseRelUsers = $sessionRelCourseRelUsers;
2197
2198
        return $this;
2199
    }
2200
2201
    public function getGender(): ?string
2202
    {
2203
        return $this->gender;
2204
    }
2205
2206
    public function setGender(?string $gender): self
2207
    {
2208
        $this->gender = $gender;
2209
2210
        return $this;
2211
    }
2212
2213
    /**
2214
     * @return Collection<int, CSurveyInvitation>
2215
     */
2216
    public function getSurveyInvitations(): Collection
2217
    {
2218
        return $this->surveyInvitations;
2219
    }
2220
2221
    public function setSurveyInvitations(Collection $surveyInvitations): self
2222
    {
2223
        $this->surveyInvitations = $surveyInvitations;
2224
2225
        return $this;
2226
    }
2227
2228
    public function getLogin(): string
2229
    {
2230
        return $this->username;
2231
    }
2232
2233
    public function setLogin(string $login): self
2234
    {
2235
        $this->username = $login;
2236
2237
        return $this;
2238
    }
2239
2240
    /**
2241
     * @return Collection<int, TrackELogin>
2242
     */
2243
    public function getLogins(): Collection
2244
    {
2245
        return $this->logins;
2246
    }
2247
2248
    public function setLogins(Collection $logins): self
2249
    {
2250
        $this->logins = $logins;
2251
2252
        return $this;
2253
    }
2254
2255
    /**
2256
     * @return Collection<int, MessageTag>
2257
     */
2258
    public function getMessageTags(): Collection
2259
    {
2260
        return $this->messageTags;
2261
    }
2262
2263
    /**
2264
     * @param Collection<int, MessageTag> $messageTags
2265
     */
2266
    public function setMessageTags(Collection $messageTags): self
2267
    {
2268
        $this->messageTags = $messageTags;
2269
2270
        return $this;
2271
    }
2272
2273
    /**
2274
     * @param null|UserCourseCategory $userCourseCategory the user_course_category
2275
     *
2276
     * @todo move in a repo
2277
     * Find the largest sort value in a given UserCourseCategory
2278
     * This method is used when we are moving a course to a different category
2279
     * and also when a user subscribes to courses (the new course is added at the end of the main category).
2280
     *
2281
     * Used to be implemented in global function \api_max_sort_value.
2282
     * Reimplemented using the ORM cache.
2283
     */
2284
    public function getMaxSortValue(?UserCourseCategory $userCourseCategory = null): int
2285
    {
2286
        $categoryCourses = $this->courses->matching(
2287
            Criteria::create()->where(Criteria::expr()->neq('relationType', COURSE_RELATION_TYPE_RRHH))->andWhere(
2288
                Criteria::expr()->eq('userCourseCat', $userCourseCategory)
2289
            )
2290
        );
2291
2292
        return $categoryCourses->isEmpty() ? 0 : max(
2293
            $categoryCourses->map(fn ($courseRelUser) => $courseRelUser->getSort())->toArray()
2294
        );
2295
    }
2296
2297
    public function hasFriendWithRelationType(self $friend, int $relationType): bool
2298
    {
2299
        $friends = $this->getFriendsByRelationType($relationType);
2300
2301
        return $friends->exists(fn (int $index, UserRelUser $userRelUser) => $userRelUser->getFriend() === $friend);
2302
    }
2303
2304
    public function isFriendWithMeByRelationType(self $friend, int $relationType): bool
2305
    {
2306
        return $this
2307
            ->getFriendsWithMeByRelationType($relationType)
2308
            ->exists(fn (int $index, UserRelUser $userRelUser) => $userRelUser->getUser() === $friend)
2309
        ;
2310
    }
2311
2312
    /**
2313
     * @param int $relationType Example: UserRelUser::USER_RELATION_TYPE_BOSS
2314
     *
2315
     * @return Collection<int, UserRelUser>
2316
     */
2317
    public function getFriendsByRelationType(int $relationType): Collection
2318
    {
2319
        $criteria = Criteria::create();
2320
        $criteria->where(Criteria::expr()->eq('relationType', $relationType));
2321
2322
        return $this->friends->matching($criteria);
2323
    }
2324
2325
    public function getFriendsWithMeByRelationType(int $relationType): Collection
2326
    {
2327
        $criteria = Criteria::create();
2328
        $criteria->where(Criteria::expr()->eq('relationType', $relationType));
2329
2330
        return $this->friendsWithMe->matching($criteria);
2331
    }
2332
2333
    public function getFriendsOfFriends(): array
2334
    {
2335
        $friendsOfFriends = [];
2336
        foreach ($this->getFriends() as $friendRelation) {
2337
            foreach ($friendRelation->getFriend()->getFriends() as $friendOfFriendRelation) {
2338
                $friendsOfFriends[] = $friendOfFriendRelation->getFriend();
2339
            }
2340
        }
2341
2342
        return $friendsOfFriends;
2343
    }
2344
2345
    /**
2346
     * @return Collection<int, SocialPost>
2347
     */
2348
    public function getSentSocialPosts(): Collection
2349
    {
2350
        return $this->sentSocialPosts;
2351
    }
2352
2353
    public function addSentSocialPost(SocialPost $sentSocialPost): self
2354
    {
2355
        if (!$this->sentSocialPosts->contains($sentSocialPost)) {
2356
            $this->sentSocialPosts[] = $sentSocialPost;
2357
            $sentSocialPost->setSender($this);
2358
        }
2359
2360
        return $this;
2361
    }
2362
2363
    /**
2364
     * @return Collection<int, SocialPost>
2365
     */
2366
    public function getReceivedSocialPosts(): Collection
2367
    {
2368
        return $this->receivedSocialPosts;
2369
    }
2370
2371
    public function addReceivedSocialPost(SocialPost $receivedSocialPost): self
2372
    {
2373
        if (!$this->receivedSocialPosts->contains($receivedSocialPost)) {
2374
            $this->receivedSocialPosts[] = $receivedSocialPost;
2375
            $receivedSocialPost->setUserReceiver($this);
2376
        }
2377
2378
        return $this;
2379
    }
2380
2381
    public function getSocialPostFeedbackBySocialPost(SocialPost $post): ?SocialPostFeedback
2382
    {
2383
        $filtered = $this->getSocialPostsFeedbacks()->filter(
2384
            fn (SocialPostFeedback $postFeedback) => $postFeedback->getSocialPost() === $post
2385
        );
2386
        if ($filtered->count() > 0) {
2387
            return $filtered->first();
2388
        }
2389
2390
        return null;
2391
    }
2392
2393
    /**
2394
     * @return Collection<int, SocialPostFeedback>
2395
     */
2396
    public function getSocialPostsFeedbacks(): Collection
2397
    {
2398
        return $this->socialPostsFeedbacks;
2399
    }
2400
2401
    public function addSocialPostFeedback(SocialPostFeedback $socialPostFeedback): self
2402
    {
2403
        if (!$this->socialPostsFeedbacks->contains($socialPostFeedback)) {
2404
            $this->socialPostsFeedbacks[] = $socialPostFeedback;
2405
            $socialPostFeedback->setUser($this);
2406
        }
2407
2408
        return $this;
2409
    }
2410
2411
    public function getSubscriptionToSession(Session $session): ?SessionRelUser
2412
    {
2413
        $criteria = Criteria::create();
2414
        $criteria->where(
2415
            Criteria::expr()->eq('session', $session)
2416
        );
2417
2418
        $match = $this->sessionsRelUser->matching($criteria);
2419
2420
        if ($match->count() > 0) {
2421
            return $match->first();
2422
        }
2423
2424
        return null;
2425
    }
2426
2427
    public function getFirstAccessToSession(Session $session): ?TrackECourseAccess
2428
    {
2429
        $criteria = Criteria::create()
2430
            ->where(
2431
                Criteria::expr()->eq('sessionId', $session->getId())
2432
            )
2433
        ;
2434
2435
        $match = $this->trackECourseAccess->matching($criteria);
2436
2437
        return $match->count() > 0 ? $match->first() : null;
2438
    }
2439
2440
    public function isCourseTutor(?Course $course = null, ?Session $session = null): bool
2441
    {
2442
        return $session?->hasCoachInCourseList($this) || $course?->getSubscriptionByUser($this)?->isTutor();
2443
    }
2444
2445
    /**
2446
     * @return Collection<int, UserAuthSource>
2447
     */
2448
    public function getAuthSources(): Collection
2449
    {
2450
        return $this->authSources;
2451
    }
2452
2453
    public function getAuthSourcesByUrl(AccessUrl $url): Collection
2454
    {
2455
        $criteria = Criteria::create();
2456
        $criteria->where(
2457
            Criteria::expr()->eq('url', $url)
2458
        );
2459
2460
        return $this->authSources->matching($criteria);
2461
    }
2462
2463
    /**
2464
     * @return array<int, string>
2465
     */
2466
    public function getAuthSourcesAuthentications(?AccessUrl $url = null): array
2467
    {
2468
        $authSources = $url ? $this->getAuthSourcesByUrl($url) : $this->getAuthSources();
2469
2470
        return $authSources->map(fn (UserAuthSource $authSource) => $authSource->getAuthentication())->toArray();
2471
    }
2472
2473
    public function addAuthSource(UserAuthSource $authSource): static
2474
    {
2475
        if (!$this->authSources->contains($authSource)) {
2476
            $this->authSources->add($authSource);
2477
            $authSource->setUser($this);
2478
        }
2479
2480
        return $this;
2481
    }
2482
2483
    public function addAuthSourceByAuthentication(string $authentication, AccessUrl $url): static
2484
    {
2485
        $authSource = (new UserAuthSource())
2486
            ->setAuthentication($authentication)
2487
            ->setUrl($url)
2488
        ;
2489
2490
        $this->addAuthSource($authSource);
2491
2492
        return $this;
2493
    }
2494
2495
    public function hasAuthSourceByAuthentication(string $authentication): bool
2496
    {
2497
        return $this->authSources->exists(
2498
            fn ($key, $authSource) => $authSource instanceof UserAuthSource
2499
                && $authSource->getAuthentication() === $authentication
2500
        );
2501
    }
2502
2503
    public function getAuthSourceByAuthentication(string $authentication): UserAuthSource
2504
    {
2505
        return $this->authSources->findFirst(
2506
            fn (UserAuthSource $authSource) => $authSource->getAuthentication() === $authentication
2507
        );
2508
    }
2509
2510
    public function removeAuthSources(): static
2511
    {
2512
        foreach ($this->authSources as $authSource) {
2513
            $authSource->setUser(null);
2514
        }
2515
2516
        $this->authSources = new ArrayCollection();
2517
2518
        return $this;
2519
    }
2520
2521
    public function removeAuthSource(UserAuthSource $authSource): static
2522
    {
2523
        if ($this->authSources->removeElement($authSource)) {
2524
            // set the owning side to null (unless already changed)
2525
            if ($authSource->getUser() === $this) {
2526
                $authSource->setUser(null);
2527
            }
2528
        }
2529
2530
        return $this;
2531
    }
2532
2533
    public function getMfaEnabled(): bool
2534
    {
2535
        return $this->mfaEnabled;
2536
    }
2537
2538
    public function setMfaEnabled(bool $mfaEnabled): self
2539
    {
2540
        $this->mfaEnabled = $mfaEnabled;
2541
2542
        return $this;
2543
    }
2544
2545
    public function getMfaService(): ?string
2546
    {
2547
        return $this->mfaService;
2548
    }
2549
2550
    public function setMfaService(?string $mfaService): self
2551
    {
2552
        $this->mfaService = $mfaService;
2553
2554
        return $this;
2555
    }
2556
2557
    public function getMfaSecret(): ?string
2558
    {
2559
        return $this->mfaSecret;
2560
    }
2561
2562
    public function setMfaSecret(?string $mfaSecret): self
2563
    {
2564
        $this->mfaSecret = $mfaSecret;
2565
2566
        return $this;
2567
    }
2568
2569
    public function getMfaBackupCodes(): ?string
2570
    {
2571
        return $this->mfaBackupCodes;
2572
    }
2573
2574
    public function setMfaBackupCodes(?string $mfaBackupCodes): self
2575
    {
2576
        $this->mfaBackupCodes = $mfaBackupCodes;
2577
2578
        return $this;
2579
    }
2580
2581
    public function getMfaLastUsed(): ?DateTimeInterface
2582
    {
2583
        return $this->mfaLastUsed;
2584
    }
2585
2586
    public function setMfaLastUsed(?DateTimeInterface $mfaLastUsed): self
2587
    {
2588
        $this->mfaLastUsed = $mfaLastUsed;
2589
2590
        return $this;
2591
    }
2592
}
2593