Passed
Push — translations ( 6cd971...bddd68 )
by Yannick
35:39 queued 27:44
created

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