Passed
Push — master ( bd8ed8...9d8dba )
by Angel Fernando Quiroz
09:46 queued 18s
created

User::setGroups()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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