Passed
Push — master ( fabd80...b89051 )
by Yannick
06:43
created

Session::setName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Entity;
8
9
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
10
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
11
use ApiPlatform\Metadata\ApiFilter;
12
use ApiPlatform\Metadata\ApiResource;
13
use ApiPlatform\Metadata\Delete;
14
use ApiPlatform\Metadata\Get;
15
use ApiPlatform\Metadata\GetCollection;
16
use ApiPlatform\Metadata\Post;
17
use ApiPlatform\Metadata\Put;
18
use ApiPlatform\Serializer\Filter\PropertyFilter;
19
use Chamilo\CoreBundle\Entity\Listener\SessionListener;
20
use Chamilo\CoreBundle\Repository\SessionRepository;
21
use DateTime;
22
use Doctrine\Common\Collections\ArrayCollection;
23
use Doctrine\Common\Collections\Collection;
24
use Doctrine\Common\Collections\Criteria;
25
use Doctrine\Common\Collections\ReadableCollection;
26
use Doctrine\ORM\Mapping as ORM;
27
use Stringable;
28
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
29
use Symfony\Component\Serializer\Annotation\Groups;
30
use Symfony\Component\Validator\Constraints as Assert;
31
32
#[ApiResource(
33
    operations: [
34
        new Get(
35
            normalizationContext: [
36
                'groups' => ['session:read', 'session:item:read'],
37
            ],
38
            security: "is_granted('ROLE_ADMIN') or is_granted('VIEW', object)"
39
        ),
40
        new Put(security: "is_granted('ROLE_ADMIN')"),
41
        new GetCollection(security: "is_granted('ROLE_ADMIN')"),
42
        new Post(security: "is_granted('ROLE_ADMIN')"),
43
        new Delete(security: "is_granted('DELETE', object)"),
44
    ],
45
    normalizationContext: ['groups' => ['session:read']],
46
    denormalizationContext: ['groups' => ['session:write']],
47
    security: "is_granted('ROLE_ADMIN')"
48
)]
49
50
#[ORM\Table(name: 'session')]
51
#[ORM\UniqueConstraint(name: 'title', columns: ['title'])]
52
#[ORM\EntityListeners([SessionListener::class])]
53
#[ORM\Entity(repositoryClass: SessionRepository::class)]
54
#[UniqueEntity('title')]
55
#[ApiFilter(filterClass: SearchFilter::class, properties: ['title' => 'partial'])]
56
#[ApiFilter(filterClass: PropertyFilter::class)]
57
#[ApiFilter(filterClass: OrderFilter::class, properties: ['id', 'title'])]
58
class Session implements ResourceWithAccessUrlInterface, \Stringable
59
{
60
    public const VISIBLE = 1;
61
    public const READ_ONLY = 2;
62
    public const INVISIBLE = 3;
63
    public const AVAILABLE = 4;
64
    public const STUDENT = 0;
65
    public const DRH = 1;
66
    public const COURSE_COACH = 2;
67
    public const GENERAL_COACH = 3;
68
    public const SESSION_ADMIN = 4;
69
70
    #[Groups([
71
        'session:read',
72
        'session_rel_user:read',
73
        'session_rel_course_rel_user:read',
74
        'course:read',
75
        'track_e_exercise:read',
76
    ])]
77
    #[ORM\Column(name: 'id', type: 'integer')]
78
    #[ORM\Id]
79
    #[ORM\GeneratedValue]
80
    protected ?int $id = null;
81
82
    /**
83
     * @var Collection<int, SessionRelCourse>
84
     */
85
    #[Groups([
86
        'session:read',
87
        'session_rel_user:read',
88
        'session_rel_course_rel_user:read',
89
    ])]
90
    #[ORM\OrderBy(['position' => 'ASC'])]
91
    #[ORM\OneToMany(
92
        mappedBy: 'session',
93
        targetEntity: SessionRelCourse::class,
94
        cascade: ['persist'],
95
        orphanRemoval: true
96
    )]
97
    protected Collection $courses;
98
99
    /**
100
     * @var Collection<int, SessionRelUser>
101
     */
102
    #[Groups([
103
        'session:read',
104
    ])]
105
    #[ORM\OneToMany(
106
        mappedBy: 'session',
107
        targetEntity: SessionRelUser::class,
108
        cascade: ['persist', 'remove'],
109
        orphanRemoval: true
110
    )]
111
    protected Collection $users;
112
113
    /**
114
     * @var Collection<int, SessionRelCourseRelUser>
115
     */
116
    #[Groups([
117
        'session:read',
118
        'session_rel_course_rel_user:read',
119
    ])]
120
    #[ORM\OneToMany(
121
        mappedBy: 'session',
122
        targetEntity: SessionRelCourseRelUser::class,
123
        cascade: ['persist'],
124
        orphanRemoval: true
125
    )]
126
    protected Collection $sessionRelCourseRelUsers;
127
128
    /**
129
     * @var Collection<int, SkillRelCourse>
130
     */
131
    #[ORM\OneToMany(
132
        mappedBy: 'session',
133
        targetEntity: SkillRelCourse::class,
134
        cascade: ['persist', 'remove']
135
    )]
136
    protected Collection $skills;
137
138
    /**
139
     * @var Collection<int, SkillRelUser>
140
     */
141
    #[ORM\OneToMany(mappedBy: 'session', targetEntity: SkillRelUser::class, cascade: ['persist'])]
142
    protected Collection $issuedSkills;
143
144
    /**
145
     * @var Collection<int, EntityAccessUrlInterface>
146
     */
147
    #[ORM\OneToMany(
148
        mappedBy: 'session',
149
        targetEntity: AccessUrlRelSession::class,
150
        cascade: ['persist'],
151
        orphanRemoval: true
152
    )]
153
    protected Collection $urls;
154
155
    /**
156
     * @var Collection<int, ResourceLink>
157
     */
158
    #[ORM\OneToMany(mappedBy: 'session', targetEntity: ResourceLink::class, cascade: ['remove'], orphanRemoval: true)]
159
    protected Collection $resourceLinks;
160
161
    protected AccessUrl $currentUrl;
162
163
    protected ?Course $currentCourse = null;
164
165
    #[Assert\NotBlank]
166
    #[Groups([
167
        'session:read',
168
        'session:write',
169
        'session_rel_course_rel_user:read',
170
        'document:read',
171
        'session_rel_user:read',
172
        'course:read',
173
        'track_e_exercise:read',
174
    ])]
175
    #[ORM\Column(name: 'title', type: 'string', length: 150)]
176
    protected string $title;
177
178
    #[Groups([
179
        'session:read',
180
        'session:write',
181
    ])]
182
    #[ORM\Column(name: 'description', type: 'text', unique: false, nullable: true)]
183
    protected ?string $description;
184
185
    #[Groups([
186
        'session:read',
187
        'session:write',
188
    ])]
189
    #[ORM\Column(name: 'show_description', type: 'boolean', nullable: true)]
190
    protected ?bool $showDescription;
191
192
    #[Groups(['session:read', 'session:write'])]
193
    #[ORM\Column(name: 'duration', type: 'integer', nullable: true)]
194
    protected ?int $duration = null;
195
196
    #[Groups(['session:read'])]
197
    #[ORM\Column(name: 'nbr_courses', type: 'integer', unique: false, nullable: false)]
198
    protected int $nbrCourses;
199
200
    #[Groups(['session:read'])]
201
    #[ORM\Column(name: 'nbr_users', type: 'integer', unique: false, nullable: false)]
202
    protected int $nbrUsers;
203
204
    #[Groups(['session:read'])]
205
    #[ORM\Column(name: 'nbr_classes', type: 'integer', unique: false, nullable: false)]
206
    protected int $nbrClasses;
207
208
    #[Groups([
209
        'session:read',
210
        'session:write',
211
    ])]
212
    #[ORM\Column(name: 'visibility', type: 'integer')]
213
    protected int $visibility;
214
215
    #[ORM\ManyToOne(targetEntity: Promotion::class, cascade: ['persist'], inversedBy: 'sessions')]
216
    #[ORM\JoinColumn(name: 'promotion_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
217
    protected ?Promotion $promotion = null;
218
219
    #[Groups([
220
        'session:read',
221
        'session:write',
222
        'session_rel_user:read',
223
        'session_rel_course_rel_user:read',
224
    ])]
225
    #[ORM\Column(name: 'display_start_date', type: 'datetime', unique: false, nullable: true)]
226
    protected ?DateTime $displayStartDate;
227
228
    #[Groups([
229
        'session:read',
230
        'session:write',
231
        'session_rel_user:read',
232
        'session_rel_course_rel_user:read',
233
    ])]
234
    #[ORM\Column(name: 'display_end_date', type: 'datetime', unique: false, nullable: true)]
235
    protected ?DateTime $displayEndDate;
236
237
    #[Groups([
238
        'session:read',
239
        'session:write',
240
        'session_rel_user:read',
241
        'session_rel_course_rel_user:read',
242
    ])]
243
    #[ORM\Column(name: 'access_start_date', type: 'datetime', unique: false, nullable: true)]
244
    protected ?DateTime $accessStartDate;
245
246
    #[Groups([
247
        'session:read',
248
        'session:write',
249
        'session_rel_user:read',
250
        'session_rel_course_rel_user:read',
251
    ])]
252
    #[ORM\Column(name: 'access_end_date', type: 'datetime', unique: false, nullable: true)]
253
    protected ?DateTime $accessEndDate;
254
255
    #[Groups([
256
        'session:read',
257
        'session:write',
258
        'session_rel_user:read',
259
        'session_rel_course_rel_user:read',
260
    ])]
261
    #[ORM\Column(name: 'coach_access_start_date', type: 'datetime', unique: false, nullable: true)]
262
    protected ?DateTime $coachAccessStartDate;
263
264
    #[Groups([
265
        'session:read',
266
        'session:write',
267
        'session_rel_user:read',
268
        'session_rel_course_rel_user:read',
269
    ])]
270
    #[ORM\Column(name: 'coach_access_end_date', type: 'datetime', unique: false, nullable: true)]
271
    protected ?DateTime $coachAccessEndDate;
272
273
    #[ORM\Column(name: 'position', type: 'integer', nullable: false, options: ['default' => 0])]
274
    protected int $position;
275
276
    #[Groups(['session:read'])]
277
    #[ORM\Column(name: 'status', type: 'integer', nullable: false)]
278
    protected int $status;
279
280
    #[Groups(['session:read', 'session:write', 'session_rel_user:read'])]
281
    #[ORM\ManyToOne(targetEntity: SessionCategory::class, inversedBy: 'sessions')]
282
    #[ORM\JoinColumn(name: 'session_category_id', referencedColumnName: 'id')]
283
    protected ?SessionCategory $category = null;
284
285
    #[ORM\Column(
286
        name: 'send_subscription_notification',
287
        type: 'boolean',
288
        nullable: false,
289
        options: ['default' => false]
290
    )]
291
    protected bool $sendSubscriptionNotification;
292
293
    /**
294
     * Image illustrating the session (was extra field 'image' in 1.11).
295
     */
296
    #[ORM\ManyToOne(targetEntity: Asset::class, cascade: ['remove'])]
297
    #[ORM\JoinColumn(name: 'image_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
298
    protected ?Asset $image = null;
299
300
    public function __construct()
301
    {
302
        $this->skills = new ArrayCollection();
303
        $this->issuedSkills = new ArrayCollection();
304
        $this->resourceLinks = new ArrayCollection();
305
        $this->courses = new ArrayCollection();
306
        $this->users = new ArrayCollection();
307
        $this->sessionRelCourseRelUsers = new ArrayCollection();
308
        $this->urls = new ArrayCollection();
309
        $this->duration = 0;
310
        $this->description = '';
311
        $this->nbrClasses = 0;
312
        $this->nbrUsers = 0;
313
        $this->nbrCourses = 0;
314
        $this->sendSubscriptionNotification = false;
315
        $now = new DateTime();
316
        $this->displayStartDate = $now;
317
        $this->displayEndDate = $now;
318
        $this->accessStartDate = $now;
319
        $this->accessEndDate = $now;
320
        $this->coachAccessStartDate = $now;
321
        $this->coachAccessEndDate = $now;
322
        $this->visibility = 1;
323
        $this->showDescription = false;
324
        $this->category = null;
325
        $this->status = 0;
326
        $this->position = 0;
327
    }
328
329
    public function __toString(): string
330
    {
331
        return $this->getTitle();
332
    }
333
334
    public static function getRelationTypeList(): array
335
    {
336
        return [self::STUDENT, self::DRH, self::COURSE_COACH, self::GENERAL_COACH, self::SESSION_ADMIN];
337
    }
338
339
    public static function getStatusList(): array
340
    {
341
        return [
342
            self::VISIBLE => 'status_visible',
343
            self::READ_ONLY => 'status_read_only',
344
            self::INVISIBLE => 'status_invisible',
345
            self::AVAILABLE => 'status_available',
346
        ];
347
    }
348
349
    public function getDuration(): ?int
350
    {
351
        return $this->duration;
352
    }
353
354
    public function setDuration(int $duration): self
355
    {
356
        $this->duration = $duration;
357
358
        return $this;
359
    }
360
361
    public function getShowDescription(): bool
362
    {
363
        return $this->showDescription;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->showDescription could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
364
    }
365
366
    public function setShowDescription(bool $showDescription): self
367
    {
368
        $this->showDescription = $showDescription;
369
370
        return $this;
371
    }
372
373
    /**
374
     * @return Collection<int, SessionRelUser>
375
     */
376
    public function getUsers(): Collection
377
    {
378
        return $this->users;
379
    }
380
381
    public function setUsers(Collection $users): self
382
    {
383
        $this->users = new ArrayCollection();
384
        foreach ($users as $user) {
385
            $this->addUserSubscription($user);
386
        }
387
388
        return $this;
389
    }
390
391
    public function addUserSubscription(SessionRelUser $subscription): void
392
    {
393
        $subscription->setSession($this);
394
        if (!$this->hasUser($subscription)) {
395
            $this->users->add($subscription);
396
            $this->nbrUsers++;
397
        }
398
    }
399
400
    public function hasUser(SessionRelUser $subscription): bool
401
    {
402
        if (0 !== $this->getUsers()->count()) {
403
            $criteria = Criteria::create()
404
                ->where(
405
                    Criteria::expr()->eq('user', $subscription->getUser())
406
                )
407
                ->andWhere(
408
                    Criteria::expr()->eq('session', $subscription->getSession())
409
                )
410
                ->andWhere(
411
                    Criteria::expr()->eq('relationType', $subscription->getRelationType())
412
                )
413
            ;
414
            $relation = $this->getUsers()->matching($criteria);
415
416
            return $relation->count() > 0;
417
        }
418
419
        return false;
420
    }
421
422
    public function hasCourse(Course $course): bool
423
    {
424
        if (0 !== $this->getCourses()->count()) {
425
            $criteria = Criteria::create()->where(Criteria::expr()->eq('course', $course));
426
            $relation = $this->getCourses()->matching($criteria);
427
428
            return $relation->count() > 0;
429
        }
430
431
        return false;
432
    }
433
434
    public function getCourses(): Collection
435
    {
436
        return $this->courses;
437
    }
438
439
    public function setCourses(ArrayCollection $courses): void
440
    {
441
        $this->courses = new ArrayCollection();
442
        foreach ($courses as $course) {
443
            $this->addCourses($course);
444
        }
445
    }
446
447
    public function addCourses(SessionRelCourse $course): void
448
    {
449
        $course->setSession($this);
450
        $this->courses->add($course);
451
    }
452
453
    public function removeCourses(SessionRelCourse $course): void
454
    {
455
        foreach ($this->courses as $key => $value) {
456
            if ($value->getId() === $course->getId()) {
457
                unset($this->courses[$key]);
458
            }
459
        }
460
    }
461
462
    public function getId(): ?int
463
    {
464
        return $this->id;
465
    }
466
467
    /**
468
     * Remove course subscription for a user.
469
     * If user status in session is student, then decrease number of course users.
470
     */
471
    public function removeUserCourseSubscription(User $user, Course $course): void
472
    {
473
        foreach ($this->sessionRelCourseRelUsers as $i => $sessionRelUser) {
474
            if ($sessionRelUser->getCourse()->getId() === $course->getId()
475
                && $sessionRelUser->getUser()->getId() === $user->getId()
476
            ) {
477
                if (self::STUDENT === $this->sessionRelCourseRelUsers[$i]->getStatus()) {
478
                    $sessionCourse = $this->getCourseSubscription($course);
479
                    $sessionCourse->setNbrUsers($sessionCourse->getNbrUsers() - 1);
480
                }
481
482
                unset($this->sessionRelCourseRelUsers[$i]);
483
            }
484
        }
485
    }
486
487
    public function getStatus(): int
488
    {
489
        return $this->status;
490
    }
491
492
    public function setStatus(int $status): self
493
    {
494
        $this->status = $status;
495
496
        return $this;
497
    }
498
499
    public function setTitle(string $title): self
500
    {
501
        $this->title = $title;
502
503
        return $this;
504
    }
505
506
    public function getCourseSubscription(Course $course): ?SessionRelCourse
507
    {
508
        $criteria = Criteria::create()->where(Criteria::expr()->eq('course', $course));
509
510
        return $this->courses->matching($criteria)->current();
511
    }
512
513
    public function getTitle(): string
514
    {
515
        return $this->title;
516
    }
517
518
    public function getNbrUsers(): int
519
    {
520
        return $this->nbrUsers;
521
    }
522
523
    public function setNbrUsers(int $nbrUsers): self
524
    {
525
        $this->nbrUsers = $nbrUsers;
526
527
        return $this;
528
    }
529
530
    public function getAllUsersFromCourse(int $status): Collection
531
    {
532
        $criteria = Criteria::create()->where(Criteria::expr()->eq('status', $status));
533
534
        return $this->getSessionRelCourseRelUsers()->matching($criteria);
535
    }
536
537
    public function getSessionRelCourseRelUsers(): Collection
538
    {
539
        return $this->sessionRelCourseRelUsers;
540
    }
541
542
    public function setSessionRelCourseRelUsers(Collection $sessionRelCourseRelUsers): self
543
    {
544
        $this->sessionRelCourseRelUsers = new ArrayCollection();
545
        foreach ($sessionRelCourseRelUsers as $item) {
546
            $this->addSessionRelCourseRelUser($item);
547
        }
548
549
        return $this;
550
    }
551
552
    public function addSessionRelCourseRelUser(SessionRelCourseRelUser $sessionRelCourseRelUser): void
553
    {
554
        $sessionRelCourseRelUser->setSession($this);
555
        if (!$this->hasUserCourseSubscription($sessionRelCourseRelUser)) {
556
            $this->sessionRelCourseRelUsers->add($sessionRelCourseRelUser);
557
        }
558
    }
559
560
    public function hasUserCourseSubscription(SessionRelCourseRelUser $subscription): bool
561
    {
562
        if (0 !== $this->getSessionRelCourseRelUsers()->count()) {
563
            $criteria = Criteria::create()
564
                ->where(
565
                    Criteria::expr()->eq('user', $subscription->getUser())
566
                )
567
                ->andWhere(
568
                    Criteria::expr()->eq('course', $subscription->getCourse())
569
                )
570
                ->andWhere(
571
                    Criteria::expr()->eq('session', $subscription->getSession())
572
                )
573
            ;
574
            $relation = $this->getSessionRelCourseRelUsers()->matching($criteria);
575
576
            return $relation->count() > 0;
577
        }
578
579
        return false;
580
    }
581
582
    public function getSessionRelCourseByUser(User $user, int $status = null): Collection
583
    {
584
        $criteria = Criteria::create()->where(Criteria::expr()->eq('user', $user));
585
        if (null !== $status) {
586
            $criteria->andWhere(Criteria::expr()->eq('status', $status));
587
        }
588
589
        return $this->sessionRelCourseRelUsers->matching($criteria);
590
    }
591
592
    public function getDescription(): ?string
593
    {
594
        return $this->description;
595
    }
596
597
    public function setDescription(string $description): self
598
    {
599
        $this->description = $description;
600
601
        return $this;
602
    }
603
604
    public function getNbrCourses(): int
605
    {
606
        return $this->nbrCourses;
607
    }
608
609
    public function setNbrCourses(int $nbrCourses): self
610
    {
611
        $this->nbrCourses = $nbrCourses;
612
613
        return $this;
614
    }
615
616
    public function getNbrClasses(): int
617
    {
618
        return $this->nbrClasses;
619
    }
620
621
    public function setNbrClasses(int $nbrClasses): self
622
    {
623
        $this->nbrClasses = $nbrClasses;
624
625
        return $this;
626
    }
627
628
    public function getVisibility(): int
629
    {
630
        return $this->visibility;
631
    }
632
633
    public function setVisibility(int $visibility): self
634
    {
635
        $this->visibility = $visibility;
636
637
        return $this;
638
    }
639
640
    public function getPromotion(): ?Promotion
641
    {
642
        return $this->promotion;
643
    }
644
645
    public function setPromotion(?Promotion $promotion): self
646
    {
647
        $this->promotion = $promotion;
648
649
        return $this;
650
    }
651
652
    public function getDisplayStartDate(): ?DateTime
653
    {
654
        return $this->displayStartDate;
655
    }
656
657
    public function setDisplayStartDate(?DateTime $displayStartDate): self
658
    {
659
        $this->displayStartDate = $displayStartDate;
660
661
        return $this;
662
    }
663
664
    public function getDisplayEndDate(): ?DateTime
665
    {
666
        return $this->displayEndDate;
667
    }
668
669
    public function setDisplayEndDate(?DateTime $displayEndDate): self
670
    {
671
        $this->displayEndDate = $displayEndDate;
672
673
        return $this;
674
    }
675
676
    public function getGeneralCoaches(): ReadableCollection
677
    {
678
        return $this->getGeneralCoachesSubscriptions()
679
            ->map(fn (SessionRelUser $subscription) => $subscription->getUser())
680
        ;
681
    }
682
683
    public function getGeneralCoachesSubscriptions(): Collection
684
    {
685
        $criteria = Criteria::create()->where(Criteria::expr()->eq('relationType', self::GENERAL_COACH));
686
687
        return $this->users->matching($criteria);
688
    }
689
690
    public function hasUserAsGeneralCoach(User $user): bool
691
    {
692
        $criteria = Criteria::create()
693
            ->where(
694
                Criteria::expr()->eq('relationType', self::GENERAL_COACH)
695
            )
696
            ->andWhere(
697
                Criteria::expr()->eq('user', $user)
698
            )
699
        ;
700
701
        return $this->users->matching($criteria)->count() > 0;
702
    }
703
704
    public function addGeneralCoach(User $coach): self
705
    {
706
        return $this->addUserInSession(self::GENERAL_COACH, $coach);
707
    }
708
709
    public function addUserInSession(int $relationType, User $user): self
710
    {
711
        $sessionRelUser = (new SessionRelUser())->setUser($user)->setRelationType($relationType);
712
        $this->addUserSubscription($sessionRelUser);
713
714
        return $this;
715
    }
716
717
    public function removeGeneralCoach(User $user): self
718
    {
719
        $this->removeUserInSession(self::GENERAL_COACH, $user);
720
721
        return $this;
722
    }
723
724
    public function removeUserInSession(int $relationType, User $user): self
725
    {
726
        $criteria = Criteria::create()
727
            ->where(
728
                Criteria::expr()->eq('relationType', $relationType)
729
            )
730
            ->andWhere(
731
                Criteria::expr()->eq('user', $user)
732
            )
733
        ;
734
        $subscriptions = $this->users->matching($criteria);
735
736
        foreach ($subscriptions as $subscription) {
737
            $this->removeUserSubscription($subscription);
738
        }
739
740
        return $this;
741
    }
742
743
    public function removeUserSubscription(SessionRelUser $subscription): self
744
    {
745
        if ($this->hasUser($subscription)) {
746
            $subscription->setSession(null);
747
            $this->users->removeElement($subscription);
748
            $this->nbrUsers--;
749
        }
750
751
        return $this;
752
    }
753
754
    public function getCategory(): ?SessionCategory
755
    {
756
        return $this->category;
757
    }
758
759
    public function setCategory(?SessionCategory $category): self
760
    {
761
        $this->category = $category;
762
763
        return $this;
764
    }
765
766
    /**
767
     * Check if session is visible.
768
     */
769
    public function isActive(): bool
770
    {
771
        $now = new Datetime('now');
772
773
        return $now > $this->getAccessStartDate();
774
    }
775
776
    public function getAccessStartDate(): ?DateTime
777
    {
778
        return $this->accessStartDate;
779
    }
780
781
    public function setAccessStartDate(?DateTime $accessStartDate): self
782
    {
783
        $this->accessStartDate = $accessStartDate;
784
785
        return $this;
786
    }
787
788
    public function isActiveForStudent(): bool
789
    {
790
        $start = $this->getAccessStartDate();
791
        $end = $this->getAccessEndDate();
792
793
        return $this->compareDates($start, $end);
794
    }
795
796
    public function getAccessEndDate(): ?DateTime
797
    {
798
        return $this->accessEndDate;
799
    }
800
801
    public function setAccessEndDate(?DateTime $accessEndDate): self
802
    {
803
        $this->accessEndDate = $accessEndDate;
804
805
        return $this;
806
    }
807
808
    public function isActiveForCoach(): bool
809
    {
810
        $start = $this->getCoachAccessStartDate();
811
        $end = $this->getCoachAccessEndDate();
812
813
        return $this->compareDates($start, $end);
814
    }
815
816
    public function getCoachAccessStartDate(): ?DateTime
817
    {
818
        return $this->coachAccessStartDate;
819
    }
820
821
    public function setCoachAccessStartDate(?DateTime $coachAccessStartDate): self
822
    {
823
        $this->coachAccessStartDate = $coachAccessStartDate;
824
825
        return $this;
826
    }
827
828
    public function getCoachAccessEndDate(): ?DateTime
829
    {
830
        return $this->coachAccessEndDate;
831
    }
832
833
    public function setCoachAccessEndDate(?DateTime $coachAccessEndDate): self
834
    {
835
        $this->coachAccessEndDate = $coachAccessEndDate;
836
837
        return $this;
838
    }
839
840
    /**
841
     * Compare the current date with start and end access dates.
842
     * Either missing date is interpreted as no limit.
843
     *
844
     * @return bool whether now is between the session access start and end dates
845
     */
846
    public function isCurrentlyAccessible(): bool
847
    {
848
        $now = new Datetime();
849
850
        return (null === $this->accessStartDate || $this->accessStartDate < $now)
851
            && (null === $this->accessEndDate || $now < $this->accessEndDate);
852
    }
853
854
    public function addCourse(Course $course): self
855
    {
856
        $sessionRelCourse = (new SessionRelCourse())->setCourse($course);
857
        $this->addCourses($sessionRelCourse);
858
859
        return $this;
860
    }
861
862
    /**
863
     * Removes a course from this session.
864
     *
865
     * @param Course $course the course to remove from this session
866
     *
867
     * @return bool whether the course was actually found in this session and removed from it
868
     */
869
    public function removeCourse(Course $course): bool
870
    {
871
        $relCourse = $this->getCourseSubscription($course);
872
        if (null !== $relCourse) {
873
            $this->courses->removeElement($relCourse);
874
            $this->setNbrCourses(\count($this->courses));
875
876
            return true;
877
        }
878
879
        return false;
880
    }
881
882
    /**
883
     * Add a user course subscription.
884
     * If user status in session is student, then increase number of course users.
885
     * Status example: Session::STUDENT.
886
     */
887
    public function addUserInCourse(int $status, User $user, Course $course): SessionRelCourseRelUser
888
    {
889
        $userRelCourseRelSession = (new SessionRelCourseRelUser())
890
            ->setCourse($course)
891
            ->setUser($user)
892
            ->setSession($this)
893
            ->setStatus($status)
894
        ;
895
896
        $this->addSessionRelCourseRelUser($userRelCourseRelSession);
897
898
        if (self::STUDENT === $status) {
899
            $sessionCourse = $this->getCourseSubscription($course);
900
            $sessionCourse->setNbrUsers($sessionCourse->getNbrUsers() + 1);
901
        }
902
903
        return $userRelCourseRelSession;
904
    }
905
906
    /**
907
     * currentCourse is set in CourseListener.
908
     */
909
    public function getCurrentCourse(): ?Course
910
    {
911
        return $this->currentCourse;
912
    }
913
914
    /**
915
     * currentCourse is set in CourseListener.
916
     */
917
    public function setCurrentCourse(Course $course): self
918
    {
919
        // If the session is registered in the course session list.
920
        $exists = $this->getCourses()
921
            ->exists(
922
                fn ($key, $element) => $course->getId() === $element->getCourse()->getId()
923
            )
924
        ;
925
926
        if ($exists) {
927
            $this->currentCourse = $course;
928
        }
929
930
        return $this;
931
    }
932
933
    public function getSendSubscriptionNotification(): bool
934
    {
935
        return $this->sendSubscriptionNotification;
936
    }
937
938
    public function setSendSubscriptionNotification(bool $sendNotification): self
939
    {
940
        $this->sendSubscriptionNotification = $sendNotification;
941
942
        return $this;
943
    }
944
945
    /**
946
     * Get user from course by status.
947
     */
948
    public function getSessionRelCourseRelUsersByStatus(Course $course, int $status): Collection
949
    {
950
        $criteria = Criteria::create()
951
            ->where(
952
                Criteria::expr()->eq('course', $course)
953
            )
954
            ->andWhere(
955
                Criteria::expr()->eq('status', $status)
956
            )
957
        ;
958
959
        return $this->sessionRelCourseRelUsers->matching($criteria);
960
    }
961
962
    public function getIssuedSkills(): Collection
963
    {
964
        return $this->issuedSkills;
965
    }
966
967
    public function getCurrentUrl(): AccessUrl
968
    {
969
        return $this->currentUrl;
970
    }
971
972
    public function setCurrentUrl(AccessUrl $url): self
973
    {
974
        $urlList = $this->getUrls();
975
        foreach ($urlList as $item) {
976
            if ($item->getUrl()->getId() === $url->getId()) {
977
                $this->currentUrl = $url;
978
979
                break;
980
            }
981
        }
982
983
        return $this;
984
    }
985
986
    /**
987
     * @return Collection<int, EntityAccessUrlInterface>
988
     */
989
    public function getUrls(): Collection
990
    {
991
        return $this->urls;
992
    }
993
994
    public function setUrls(Collection $urls): self
995
    {
996
        $this->urls = new ArrayCollection();
997
        foreach ($urls as $url) {
998
            $this->addUrls($url);
999
        }
1000
1001
        return $this;
1002
    }
1003
1004
    public function addUrls(AccessUrlRelSession $url): self
1005
    {
1006
        $url->setSession($this);
1007
        $this->urls->add($url);
1008
1009
        return $this;
1010
    }
1011
1012
    public function addAccessUrl(?AccessUrl $url): self
1013
    {
1014
        $accessUrlRelSession = new AccessUrlRelSession();
1015
        $accessUrlRelSession->setUrl($url);
1016
        $accessUrlRelSession->setSession($this);
1017
        $this->addUrls($accessUrlRelSession);
1018
1019
        return $this;
1020
    }
1021
1022
    public function getPosition(): int
1023
    {
1024
        return $this->position;
1025
    }
1026
1027
    public function setPosition(int $position): self
1028
    {
1029
        $this->position = $position;
1030
1031
        return $this;
1032
    }
1033
1034
    public function getSessionAdmins(): ReadableCollection
1035
    {
1036
        return $this->getGeneralAdminsSubscriptions()
1037
            ->map(fn (SessionRelUser $subscription) => $subscription->getUser())
1038
        ;
1039
    }
1040
1041
    public function getGeneralAdminsSubscriptions(): Collection
1042
    {
1043
        $criteria = Criteria::create()->where(Criteria::expr()->eq('relationType', self::SESSION_ADMIN));
1044
1045
        return $this->users->matching($criteria);
1046
    }
1047
1048
    public function hasUserAsSessionAdmin(User $user): bool
1049
    {
1050
        $criteria = Criteria::create()
1051
            ->where(
1052
                Criteria::expr()->eq('relationType', self::SESSION_ADMIN)
1053
            )
1054
            ->andWhere(
1055
                Criteria::expr()->eq('user', $user)
1056
            )
1057
        ;
1058
1059
        return $this->users->matching($criteria)->count() > 0;
1060
    }
1061
1062
    public function addSessionAdmin(User $sessionAdmin): self
1063
    {
1064
        return $this->addUserInSession(self::SESSION_ADMIN, $sessionAdmin);
1065
    }
1066
1067
    public function getSkills(): Collection
1068
    {
1069
        return $this->skills;
1070
    }
1071
1072
    public function getResourceLinks(): Collection
1073
    {
1074
        return $this->resourceLinks;
1075
    }
1076
1077
    public function getImage(): ?Asset
1078
    {
1079
        return $this->image;
1080
    }
1081
1082
    public function setImage(?Asset $asset): self
1083
    {
1084
        $this->image = $asset;
1085
1086
        return $this;
1087
    }
1088
1089
    public function hasImage(): bool
1090
    {
1091
        return null !== $this->image;
1092
    }
1093
1094
    /**
1095
     * Check if $user is course coach in any course.
1096
     */
1097
    public function hasCoachInCourseList(User $user): bool
1098
    {
1099
        foreach ($this->courses as $sessionCourse) {
1100
            if ($this->hasCourseCoachInCourse($user, $sessionCourse->getCourse())) {
1101
                return true;
1102
            }
1103
        }
1104
1105
        return false;
1106
    }
1107
1108
    public function hasCourseCoachInCourse(User $user, Course $course = null): bool
1109
    {
1110
        if (null === $course) {
1111
            return false;
1112
        }
1113
1114
        return $this->hasUserInCourse($user, $course, self::COURSE_COACH);
1115
    }
1116
1117
    /**
1118
     * @param int $status if not set it will check if the user is registered
1119
     *                    with any status
1120
     */
1121
    public function hasUserInCourse(User $user, Course $course, int $status = null): bool
1122
    {
1123
        $relation = $this->getUserInCourse($user, $course, $status);
1124
1125
        return $relation->count() > 0;
1126
    }
1127
1128
    public function getUserInCourse(User $user, Course $course, int $status = null): Collection
1129
    {
1130
        $criteria = Criteria::create()
1131
            ->where(
1132
                Criteria::expr()->eq('course', $course)
1133
            )
1134
            ->andWhere(
1135
                Criteria::expr()->eq('user', $user)
1136
            )
1137
        ;
1138
1139
        if (null !== $status) {
1140
            $criteria->andWhere(Criteria::expr()->eq('status', $status));
1141
        }
1142
1143
        return $this->getSessionRelCourseRelUsers()->matching($criteria);
1144
    }
1145
1146
    /**
1147
     * Check if $user is student in any course.
1148
     */
1149
    public function hasStudentInCourseList(User $user): bool
1150
    {
1151
        foreach ($this->courses as $sessionCourse) {
1152
            if ($this->hasStudentInCourse($user, $sessionCourse->getCourse())) {
1153
                return true;
1154
            }
1155
        }
1156
1157
        return false;
1158
    }
1159
1160
    public function hasStudentInCourse(User $user, Course $course): bool
1161
    {
1162
        return $this->hasUserInCourse($user, $course, self::STUDENT);
1163
    }
1164
1165
    protected function compareDates(?DateTime $start, DateTime $end = null): bool
1166
    {
1167
        $now = new Datetime('now');
1168
1169
        if (!empty($start) && !empty($end) && ($now >= $start && $now <= $end)) {
1170
            return true;
1171
        }
1172
1173
        if (!empty($start) && $now >= $start) {
1174
            return true;
1175
        }
1176
1177
        return !empty($end) && $now <= $end;
1178
    }
1179
}
1180