Passed
Push — master ( 1e0b50...40a262 )
by Angel Fernando Quiroz
09:11
created

User::getPortals()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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