Passed
Push — master ( 5a5c46...59256e )
by Julito
08:25
created

User::getMaxSortValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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