Passed
Push — master ( 35e116...03a9f3 )
by Angel Fernando Quiroz
10:35 queued 19s
created

Session::addUserInSession()   B

Complexity

Conditions 9
Paths 5

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 17
nc 5
nop 2
dl 0
loc 32
rs 8.0555
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\Metadata\ApiResource;
10
use ApiPlatform\Metadata\Delete;
11
use ApiPlatform\Metadata\Get;
12
use ApiPlatform\Metadata\GetCollection;
13
use ApiPlatform\Metadata\Link;
14
use ApiPlatform\Metadata\Post;
15
use ApiPlatform\Metadata\Put;
16
use Chamilo\CoreBundle\Controller\Api\CreateSessionWithUsersAndCoursesAction;
17
use Chamilo\CoreBundle\Dto\CreateSessionWithUsersAndCoursesInput;
18
use Chamilo\CoreBundle\Entity\Listener\SessionListener;
19
use Chamilo\CoreBundle\Repository\SessionRepository;
20
use Chamilo\CoreBundle\State\UserSessionSubscriptionsStateProvider;
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 LogicException;
28
use Stringable;
29
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
30
use Symfony\Component\Serializer\Annotation\Groups;
31
use Symfony\Component\Validator\Constraints as Assert;
32
33
#[ApiResource(
34
    operations: [
35
        new Get(
36
            uriTemplate: '/sessions/{id}',
37
            normalizationContext: [
38
                'groups' => ['session:basic'],
39
            ],
40
            security: "is_granted('ROLE_ADMIN') or is_granted('VIEW', object)"
41
        ),
42
        new Put(security: "is_granted('ROLE_ADMIN')"),
43
        new GetCollection(
44
            security: "is_granted('ROLE_ADMIN')",
45
            filters: [
46
                'session.search_filter',
47
                'session.property_filter',
48
                'session.order_filter',
49
                'session.group_filter',
50
            ]
51
        ),
52
        new GetCollection(
53
            uriTemplate: '/users/{id}/session_subscriptions/past.{_format}',
54
            uriVariables: [
55
                'id' => new Link(
56
                    fromClass: User::class,
57
                ),
58
            ],
59
            paginationEnabled: false,
60
            normalizationContext: [
61
                'groups' => [
62
                    'user_subscriptions:sessions',
63
                ],
64
            ],
65
            security: "is_granted('ROLE_USER')",
66
            name: 'user_session_subscriptions_past',
67
            provider: UserSessionSubscriptionsStateProvider::class,
68
        ),
69
        new GetCollection(
70
            uriTemplate: '/users/{id}/session_subscriptions/current.{_format}',
71
            uriVariables: [
72
                'id' => new Link(
73
                    fromClass: User::class,
74
                ),
75
            ],
76
            normalizationContext: [
77
                'groups' => [
78
                    'user_subscriptions:sessions',
79
                ],
80
            ],
81
            security: "is_granted('ROLE_USER')",
82
            name: 'user_session_subscriptions_current',
83
            provider: UserSessionSubscriptionsStateProvider::class,
84
        ),
85
        new GetCollection(
86
            uriTemplate: '/users/{id}/session_subscriptions/upcoming.{_format}',
87
            uriVariables: [
88
                'id' => new Link(
89
                    fromClass: User::class,
90
                ),
91
            ],
92
            normalizationContext: [
93
                'groups' => [
94
                    'user_subscriptions:sessions',
95
                ],
96
            ],
97
            security: "is_granted('ROLE_USER')",
98
            name: 'user_session_subscriptions_upcoming',
99
            provider: UserSessionSubscriptionsStateProvider::class,
100
        ),
101
        new Post(security: "is_granted('ROLE_ADMIN')"),
102
        new Post(
103
            uriTemplate: '/advanced/create-session-with-courses-and-users',
104
            controller: CreateSessionWithUsersAndCoursesAction::class,
105
            denormalizationContext: ['groups' => ['write']],
106
            security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_SESSION_MANAGER')",
107
            input: CreateSessionWithUsersAndCoursesInput::class,
108
            output: Session::class,
109
            deserialize: true,
110
            name: 'create_session_with_courses_and_assign_users'
111
        ),
112
        new Delete(security: "is_granted('DELETE', object)"),
113
    ],
114
    normalizationContext: ['groups' => ['session:basic']],
115
    denormalizationContext: ['groups' => ['session:write']],
116
    security: "is_granted('ROLE_ADMIN')"
117
)]
118
#[ORM\Table(name: 'session')]
119
#[ORM\UniqueConstraint(name: 'title', columns: ['title'])]
120
#[ORM\EntityListeners([SessionListener::class])]
121
#[ORM\Entity(repositoryClass: SessionRepository::class)]
122
#[UniqueEntity('title')]
123
class Session implements ResourceWithAccessUrlInterface, Stringable
124
{
125
    public const READ_ONLY = 1;
126
    public const VISIBLE = 2;
127
    public const INVISIBLE = 3;
128
    public const AVAILABLE = 4;
129
    public const LIST_ONLY = 5;
130
131
    public const STUDENT = 0;
132
    public const DRH = 1;
133
    public const COURSE_COACH = 2;
134
    public const GENERAL_COACH = 3;
135
    public const SESSION_ADMIN = 4;
136
137
    public const STATUS_PLANNED = 1;
138
    public const STATUS_PROGRESS = 2;
139
    public const STATUS_FINISHED = 3;
140
    public const STATUS_CANCELLED = 4;
141
    public const STATUS_UNKNOWN = 0;
142
143
    #[Groups([
144
        'session:basic',
145
        'session:read',
146
        'session_rel_user:read',
147
        'session_rel_course_rel_user:read',
148
        'course:read',
149
        'track_e_exercise:read',
150
        'user_subscriptions:sessions',
151
    ])]
152
    #[ORM\Column(name: 'id', type: 'integer')]
153
    #[ORM\Id]
154
    #[ORM\GeneratedValue]
155
    protected ?int $id = null;
156
157
    /**
158
     * @var Collection<int, SessionRelCourse>
159
     */
160
    #[Groups([
161
        'session:read',
162
        'session_rel_user:read',
163
        'session_rel_course_rel_user:read',
164
        'user_subscriptions:sessions',
165
    ])]
166
    #[ORM\OrderBy(['position' => 'ASC'])]
167
    #[ORM\OneToMany(
168
        mappedBy: 'session',
169
        targetEntity: SessionRelCourse::class,
170
        cascade: ['persist'],
171
        fetch: 'EXTRA_LAZY',
172
        orphanRemoval: true
173
    )]
174
    protected Collection $courses;
175
176
    /**
177
     * @var Collection<int, SessionRelUser>
178
     */
179
    #[Groups([
180
        'session:read',
181
    ])]
182
    #[ORM\OneToMany(
183
        mappedBy: 'session',
184
        targetEntity: SessionRelUser::class,
185
        cascade: ['persist', 'remove'],
186
        fetch: 'EXTRA_LAZY',
187
        orphanRemoval: true
188
    )]
189
    protected Collection $users;
190
191
    /**
192
     * @var Collection<int, SessionRelCourseRelUser>
193
     */
194
    #[Groups([
195
        'session:read',
196
        'session_rel_course_rel_user:read',
197
    ])]
198
    #[ORM\OneToMany(
199
        mappedBy: 'session',
200
        targetEntity: SessionRelCourseRelUser::class,
201
        cascade: ['persist'],
202
        orphanRemoval: true
203
    )]
204
    protected Collection $sessionRelCourseRelUsers;
205
206
    /**
207
     * @var Collection<int, SkillRelCourse>
208
     */
209
    #[ORM\OneToMany(
210
        mappedBy: 'session',
211
        targetEntity: SkillRelCourse::class,
212
        cascade: ['persist', 'remove']
213
    )]
214
    protected Collection $skills;
215
216
    /**
217
     * @var Collection<int, SkillRelUser>
218
     */
219
    #[ORM\OneToMany(mappedBy: 'session', targetEntity: SkillRelUser::class, cascade: ['persist'])]
220
    protected Collection $issuedSkills;
221
222
    /**
223
     * @var Collection<int, EntityAccessUrlInterface>
224
     */
225
    #[ORM\OneToMany(
226
        mappedBy: 'session',
227
        targetEntity: AccessUrlRelSession::class,
228
        cascade: ['persist'],
229
        orphanRemoval: true
230
    )]
231
    protected Collection $urls;
232
233
    /**
234
     * @var Collection<int, ResourceLink>
235
     */
236
    #[ORM\OneToMany(mappedBy: 'session', targetEntity: ResourceLink::class, cascade: ['remove'], orphanRemoval: true)]
237
    protected Collection $resourceLinks;
238
239
    protected AccessUrl $currentUrl;
240
241
    protected ?Course $currentCourse = null;
242
243
    #[Assert\NotBlank]
244
    #[Groups([
245
        'session:basic',
246
        'session:read',
247
        'session:write',
248
        'session_rel_course_rel_user:read',
249
        'document:read',
250
        'session_rel_user:read',
251
        'course:read',
252
        'track_e_exercise:read',
253
        'calendar_event:read',
254
        'user_subscriptions:sessions',
255
    ])]
256
    #[ORM\Column(name: 'title', type: 'string', length: 150)]
257
    protected string $title;
258
259
    #[Groups([
260
        'session:basic',
261
        'session:read',
262
        'session:write',
263
    ])]
264
    #[ORM\Column(name: 'description', type: 'text', unique: false, nullable: true)]
265
    protected ?string $description;
266
267
    #[Groups([
268
        'session:read',
269
        'session:write',
270
    ])]
271
    #[ORM\Column(name: 'show_description', type: 'boolean', nullable: true)]
272
    protected ?bool $showDescription = false;
273
274
    #[Groups(['session:read', 'session:write', 'user_subscriptions:sessions'])]
275
    #[ORM\Column(name: 'duration', type: 'integer', nullable: true)]
276
    protected ?int $duration = null;
277
278
    #[Groups(['session:basic', 'session:read', 'session:write'])]
279
    #[ORM\Column(name: 'nbr_courses', type: 'integer', unique: false, nullable: false)]
280
    protected int $nbrCourses;
281
282
    #[Groups(['session:basic', 'session:read', 'session:write'])]
283
    #[ORM\Column(name: 'nbr_users', type: 'integer', unique: false, nullable: false)]
284
    protected int $nbrUsers;
285
286
    #[Groups(['session:read'])]
287
    #[ORM\Column(name: 'nbr_classes', type: 'integer', unique: false, nullable: false)]
288
    protected int $nbrClasses;
289
290
    #[Groups([
291
        'session:basic',
292
        'session:read',
293
        'session:write',
294
    ])]
295
    #[ORM\Column(name: 'visibility', type: 'integer')]
296
    protected int $visibility;
297
298
    #[ORM\ManyToOne(targetEntity: Promotion::class, cascade: ['persist'], inversedBy: 'sessions')]
299
    #[ORM\JoinColumn(name: 'promotion_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
300
    protected ?Promotion $promotion = null;
301
302
    #[Groups([
303
        'session:read',
304
        'session:write',
305
        'session_rel_user:read',
306
        'session_rel_course_rel_user:read',
307
        'user_subscriptions:sessions',
308
    ])]
309
    #[ORM\Column(name: 'display_start_date', type: 'datetime', unique: false, nullable: true)]
310
    protected ?DateTime $displayStartDate = null;
311
312
    #[Groups([
313
        'session:read',
314
        'session:write',
315
        'session_rel_user:read',
316
        'session_rel_course_rel_user:read',
317
        'user_subscriptions:sessions',
318
    ])]
319
    #[ORM\Column(name: 'display_end_date', type: 'datetime', unique: false, nullable: true)]
320
    protected ?DateTime $displayEndDate = null;
321
322
    #[Groups([
323
        'session:read',
324
        'session:write',
325
        'session_rel_user:read',
326
        'session_rel_course_rel_user:read',
327
    ])]
328
    #[ORM\Column(name: 'access_start_date', type: 'datetime', unique: false, nullable: true)]
329
    protected ?DateTime $accessStartDate = null;
330
331
    #[Groups([
332
        'session:read',
333
        'session:write',
334
        'session_rel_user:read',
335
        'session_rel_course_rel_user:read',
336
    ])]
337
    #[ORM\Column(name: 'access_end_date', type: 'datetime', unique: false, nullable: true)]
338
    protected ?DateTime $accessEndDate = null;
339
340
    #[Groups([
341
        'session:read',
342
        'session:write',
343
        'session_rel_user:read',
344
        'session_rel_course_rel_user:read',
345
    ])]
346
    #[ORM\Column(name: 'coach_access_start_date', type: 'datetime', unique: false, nullable: true)]
347
    protected ?DateTime $coachAccessStartDate = null;
348
349
    #[Groups([
350
        'session:read',
351
        'session:write',
352
        'session_rel_user:read',
353
        'session_rel_course_rel_user:read',
354
    ])]
355
    #[ORM\Column(name: 'coach_access_end_date', type: 'datetime', unique: false, nullable: true)]
356
    protected ?DateTime $coachAccessEndDate = null;
357
358
    #[ORM\Column(name: 'position', type: 'integer', nullable: false, options: ['default' => 0])]
359
    protected int $position;
360
361
    #[Groups(['session:read'])]
362
    #[ORM\Column(name: 'status', type: 'integer', nullable: false)]
363
    protected int $status;
364
365
    #[Groups(['session:read', 'session:write', 'session_rel_user:read', 'user_subscriptions:sessions'])]
366
    #[ORM\ManyToOne(targetEntity: SessionCategory::class, inversedBy: 'sessions')]
367
    #[ORM\JoinColumn(name: 'session_category_id', referencedColumnName: 'id')]
368
    protected ?SessionCategory $category = null;
369
370
    #[ORM\Column(
371
        name: 'send_subscription_notification',
372
        type: 'boolean',
373
        nullable: false,
374
        options: ['default' => false]
375
    )]
376
    protected bool $sendSubscriptionNotification;
377
378
    /**
379
     * Image illustrating the session (was extra field 'image' in 1.11).
380
     */
381
    #[Groups(['user_subscriptions:sessions'])]
382
    #[ORM\ManyToOne(targetEntity: Asset::class, cascade: ['persist', 'remove'])]
383
    #[ORM\JoinColumn(name: 'image_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
384
    protected ?Asset $image = null;
385
386
    #[Groups(['session:basic'])]
387
    private ?string $imageUrl = null;
388
389
    #[Groups(['user_subscriptions:sessions', 'session:read', 'session:item:read'])]
390
    private int $accessVisibility = 0;
391
392
    #[ORM\Column(name: 'parent_id', type: 'integer', nullable: true)]
393
    protected ?int $parentId = null;
394
395
    #[ORM\Column(name: 'days_to_reinscription', type: 'integer', nullable: true)]
396
    protected ?int $daysToReinscription = null;
397
398
    #[ORM\Column(name: 'last_repetition', type: 'boolean', nullable: false, options: ['default' => false])]
399
    protected bool $lastRepetition = false;
400
401
    #[ORM\Column(name: 'days_to_new_repetition', type: 'integer', nullable: true)]
402
    protected ?int $daysToNewRepetition = null;
403
404
    #[ORM\Column(name: 'notify_boss', type: 'boolean', options: ['default' => false])]
405
    protected bool $notifyBoss = false;
406
407
    #[Groups(['session:basic', 'session:read', 'session:write'])]
408
    #[ORM\Column(name: 'validity_in_days', type: 'integer', nullable: true)]
409
    protected ?int $validityInDays = null;
410
411
    public function __construct()
412
    {
413
        $this->skills = new ArrayCollection();
414
        $this->issuedSkills = new ArrayCollection();
415
        $this->resourceLinks = new ArrayCollection();
416
        $this->courses = new ArrayCollection();
417
        $this->users = new ArrayCollection();
418
        $this->sessionRelCourseRelUsers = new ArrayCollection();
419
        $this->urls = new ArrayCollection();
420
        $this->duration = 0;
421
        $this->description = '';
422
        $this->nbrClasses = 0;
423
        $this->nbrUsers = 0;
424
        $this->nbrCourses = 0;
425
        $this->sendSubscriptionNotification = false;
426
        $now = new DateTime();
427
        $this->displayStartDate = $now;
428
        $this->displayEndDate = $now;
429
        $this->accessStartDate = $now;
430
        $this->accessEndDate = $now;
431
        $this->coachAccessStartDate = $now;
432
        $this->coachAccessEndDate = $now;
433
        $this->visibility = 1;
434
        $this->showDescription = false;
435
        $this->category = null;
436
        $this->status = 0;
437
        $this->position = 0;
438
    }
439
440
    public function __toString(): string
441
    {
442
        return $this->getTitle();
443
    }
444
445
    public static function getRelationTypeList(): array
446
    {
447
        return [self::STUDENT, self::DRH, self::COURSE_COACH, self::GENERAL_COACH, self::SESSION_ADMIN];
448
    }
449
450
    public static function getStatusList(): array
451
    {
452
        return [
453
            self::READ_ONLY => 'status_read_only',
454
            self::VISIBLE => 'status_visible',
455
            self::INVISIBLE => 'status_invisible',
456
            self::AVAILABLE => 'status_available',
457
        ];
458
    }
459
460
    public function getDuration(): ?int
461
    {
462
        return $this->duration;
463
    }
464
465
    public function setDuration(int $duration): self
466
    {
467
        $this->duration = $duration;
468
469
        return $this;
470
    }
471
472
    public function getShowDescription(): bool
473
    {
474
        return $this->showDescription ?? false;
475
    }
476
477
    public function setShowDescription(bool $showDescription): self
478
    {
479
        $this->showDescription = $showDescription;
480
481
        return $this;
482
    }
483
484
    /**
485
     * @return Collection<int, SessionRelUser>
486
     */
487
    public function getUsers(): Collection
488
    {
489
        return $this->users;
490
    }
491
492
    public function setUsers(Collection $users): self
493
    {
494
        $this->users = new ArrayCollection();
495
        foreach ($users as $user) {
496
            $this->addUserSubscription($user);
497
        }
498
499
        return $this;
500
    }
501
502
    public function addUserSubscription(SessionRelUser $subscription): void
503
    {
504
        $subscription->setSession($this);
505
        if (!$this->hasUser($subscription)) {
506
            $this->users->add($subscription);
507
            $this->nbrUsers++;
508
        }
509
    }
510
511
    public function hasUser(SessionRelUser $subscription): bool
512
    {
513
        if (0 !== $this->getUsers()->count()) {
514
            $criteria = Criteria::create()
515
                ->where(
516
                    Criteria::expr()->eq('user', $subscription->getUser())
517
                )
518
                ->andWhere(
519
                    Criteria::expr()->eq('session', $subscription->getSession())
520
                )
521
                ->andWhere(
522
                    Criteria::expr()->eq('relationType', $subscription->getRelationType())
523
                )
524
            ;
525
            $relation = $this->getUsers()->matching($criteria);
526
527
            return $relation->count() > 0;
528
        }
529
530
        return false;
531
    }
532
533
    public function hasCourse(Course $course): bool
534
    {
535
        if (0 !== $this->getCourses()->count()) {
536
            $criteria = Criteria::create()->where(Criteria::expr()->eq('course', $course));
537
            $relation = $this->getCourses()->matching($criteria);
538
539
            return $relation->count() > 0;
540
        }
541
542
        return false;
543
    }
544
545
    /**
546
     * @return Collection<int, SessionRelCourse>
547
     */
548
    public function getCourses(): Collection
549
    {
550
        return $this->courses;
551
    }
552
553
    public function setCourses(ArrayCollection $courses): void
554
    {
555
        $this->courses = new ArrayCollection();
556
        foreach ($courses as $course) {
557
            $this->addCourses($course);
558
        }
559
    }
560
561
    public function addCourses(SessionRelCourse $course): void
562
    {
563
        $course->setSession($this);
564
        $this->courses->add($course);
565
    }
566
567
    public function removeCourses(SessionRelCourse $course): void
568
    {
569
        foreach ($this->courses as $key => $value) {
570
            if ($value->getId() === $course->getId()) {
571
                unset($this->courses[$key]);
572
            }
573
        }
574
    }
575
576
    public function getId(): ?int
577
    {
578
        return $this->id;
579
    }
580
581
    /**
582
     * Remove course subscription for a user.
583
     * If user status in session is student, then decrease number of course users.
584
     */
585
    public function removeUserCourseSubscription(User $user, Course $course): void
586
    {
587
        foreach ($this->sessionRelCourseRelUsers as $i => $sessionRelUser) {
588
            if ($sessionRelUser->getCourse()->getId() === $course->getId()
589
                && $sessionRelUser->getUser()->getId() === $user->getId()
590
            ) {
591
                if (self::STUDENT === $this->sessionRelCourseRelUsers[$i]->getStatus()) {
592
                    $sessionCourse = $this->getCourseSubscription($course);
593
                    $sessionCourse->setNbrUsers($sessionCourse->getNbrUsers() - 1);
594
                }
595
596
                unset($this->sessionRelCourseRelUsers[$i]);
597
            }
598
        }
599
    }
600
601
    public function getStatus(): int
602
    {
603
        return $this->status;
604
    }
605
606
    public function setStatus(int $status): self
607
    {
608
        $this->status = $status;
609
610
        return $this;
611
    }
612
613
    public function setTitle(string $title): self
614
    {
615
        $this->title = $title;
616
617
        return $this;
618
    }
619
620
    public function getCourseSubscription(Course $course): ?SessionRelCourse
621
    {
622
        $criteria = Criteria::create()->where(Criteria::expr()->eq('course', $course));
623
624
        return $this->courses->matching($criteria)->current();
625
    }
626
627
    public function getTitle(): string
628
    {
629
        return $this->title;
630
    }
631
632
    public function getNbrUsers(): int
633
    {
634
        return $this->nbrUsers;
635
    }
636
637
    public function setNbrUsers(int $nbrUsers): self
638
    {
639
        $this->nbrUsers = $nbrUsers;
640
641
        return $this;
642
    }
643
644
    /**
645
     * @return Collection<int, SessionRelCourseRelUser>
646
     */
647
    public function getAllUsersFromCourse(int $status): Collection
648
    {
649
        $criteria = Criteria::create()->where(Criteria::expr()->eq('status', $status));
650
651
        return $this->getSessionRelCourseRelUsers()->matching($criteria);
652
    }
653
654
    public function getSessionRelCourseRelUsers(): Collection
655
    {
656
        return $this->sessionRelCourseRelUsers;
657
    }
658
659
    public function setSessionRelCourseRelUsers(Collection $sessionRelCourseRelUsers): self
660
    {
661
        $this->sessionRelCourseRelUsers = new ArrayCollection();
662
        foreach ($sessionRelCourseRelUsers as $item) {
663
            $this->addSessionRelCourseRelUser($item);
664
        }
665
666
        return $this;
667
    }
668
669
    public function addSessionRelCourseRelUser(SessionRelCourseRelUser $sessionRelCourseRelUser): void
670
    {
671
        $sessionRelCourseRelUser->setSession($this);
672
        if (!$this->hasUserCourseSubscription($sessionRelCourseRelUser)) {
673
            $this->sessionRelCourseRelUsers->add($sessionRelCourseRelUser);
674
        }
675
    }
676
677
    public function hasUserCourseSubscription(SessionRelCourseRelUser $subscription): bool
678
    {
679
        if (0 !== $this->getSessionRelCourseRelUsers()->count()) {
680
            $criteria = Criteria::create()
681
                ->where(
682
                    Criteria::expr()->eq('user', $subscription->getUser())
683
                )
684
                ->andWhere(
685
                    Criteria::expr()->eq('course', $subscription->getCourse())
686
                )
687
                ->andWhere(
688
                    Criteria::expr()->eq('session', $subscription->getSession())
689
                )
690
            ;
691
            $relation = $this->getSessionRelCourseRelUsers()->matching($criteria);
692
693
            return $relation->count() > 0;
694
        }
695
696
        return false;
697
    }
698
699
    /**
700
     * @return Collection<int, SessionRelCourseRelUser>
701
     */
702
    public function getSessionRelCourseByUser(User $user, ?int $status = null): Collection
703
    {
704
        $criteria = Criteria::create()->where(Criteria::expr()->eq('user', $user));
705
        if (null !== $status) {
706
            $criteria->andWhere(Criteria::expr()->eq('status', $status));
707
        }
708
709
        return $this->sessionRelCourseRelUsers->matching($criteria);
710
    }
711
712
    public function getDescription(): ?string
713
    {
714
        return $this->description;
715
    }
716
717
    public function setDescription(string $description): self
718
    {
719
        $this->description = $description;
720
721
        return $this;
722
    }
723
724
    public function getNbrCourses(): int
725
    {
726
        return $this->nbrCourses;
727
    }
728
729
    public function setNbrCourses(int $nbrCourses): self
730
    {
731
        $this->nbrCourses = $nbrCourses;
732
733
        return $this;
734
    }
735
736
    public function getNbrClasses(): int
737
    {
738
        return $this->nbrClasses;
739
    }
740
741
    public function setNbrClasses(int $nbrClasses): self
742
    {
743
        $this->nbrClasses = $nbrClasses;
744
745
        return $this;
746
    }
747
748
    public function getVisibility(): int
749
    {
750
        return $this->visibility;
751
    }
752
753
    public function setVisibility(int $visibility): self
754
    {
755
        $this->visibility = $visibility;
756
757
        return $this;
758
    }
759
760
    public function getPromotion(): ?Promotion
761
    {
762
        return $this->promotion;
763
    }
764
765
    public function setPromotion(?Promotion $promotion): self
766
    {
767
        $this->promotion = $promotion;
768
769
        return $this;
770
    }
771
772
    public function getDisplayStartDate(): ?DateTime
773
    {
774
        return $this->displayStartDate;
775
    }
776
777
    public function setDisplayStartDate(?DateTime $displayStartDate): self
778
    {
779
        $this->displayStartDate = $displayStartDate;
780
781
        return $this;
782
    }
783
784
    public function getDisplayEndDate(): ?DateTime
785
    {
786
        return $this->displayEndDate;
787
    }
788
789
    public function setDisplayEndDate(?DateTime $displayEndDate): self
790
    {
791
        $this->displayEndDate = $displayEndDate;
792
793
        return $this;
794
    }
795
796
    /**
797
     * @return Collection<int, SessionRelUser>
798
     */
799
    public function getGeneralCoaches(): Collection
800
    {
801
        return $this->getGeneralCoachesSubscriptions()
802
            ->map(fn (SessionRelUser $subscription) => $subscription->getUser())
803
        ;
804
    }
805
806
    /**
807
     * @return Collection<int, SessionRelUser>
808
     */
809
    #[Groups(['session:basic', 'user_subscriptions:sessions'])]
810
    public function getGeneralCoachesSubscriptions(): Collection
811
    {
812
        $criteria = Criteria::create()->where(Criteria::expr()->eq('relationType', self::GENERAL_COACH));
813
814
        return $this->users->matching($criteria);
815
    }
816
817
    public function hasUserAsGeneralCoach(User $user): bool
818
    {
819
        $criteria = Criteria::create()
820
            ->where(
821
                Criteria::expr()->eq('relationType', self::GENERAL_COACH)
822
            )
823
            ->andWhere(
824
                Criteria::expr()->eq('user', $user)
825
            )
826
        ;
827
828
        return $this->users->matching($criteria)->count() > 0;
829
    }
830
831
    public function hasUserInSession(User $user, int $relationType): bool
832
    {
833
        $criteria = Criteria::create()
834
            ->where(Criteria::expr()->eq('user', $user))
835
            ->andWhere(Criteria::expr()->eq('relationType', $relationType))
836
        ;
837
838
        return $this->users->matching($criteria)->count() > 0;
839
    }
840
841
    public function addGeneralCoach(User $coach): self
842
    {
843
        return $this->addUserInSession(self::GENERAL_COACH, $coach);
844
    }
845
846
    public function addUserInSession(int $relationType, User $user): self
847
    {
848
        foreach ($this->getUsers() as $existingSubscription) {
849
            if (
850
                $existingSubscription->getUser()->getId() === $user->getId()
851
                && $existingSubscription->getRelationType() === $relationType
852
            ) {
853
                return $this;
854
            }
855
        }
856
857
        $sessionRelUser = (new SessionRelUser())
858
            ->setUser($user)
859
            ->setRelationType($relationType)
860
        ;
861
862
        if ($this->duration <= 0) {
863
            $isCoach = $this->hasCoach($user);
864
865
            $sessionRelUser
866
                ->setAccessStartDate(
867
                    $isCoach && $this->coachAccessStartDate ? $this->coachAccessStartDate : $this->accessStartDate
868
                )
869
                ->setAccessEndDate(
870
                    $isCoach && $this->coachAccessEndDate ? $this->coachAccessEndDate : $this->accessEndDate
871
                )
872
            ;
873
        }
874
875
        $this->addUserSubscription($sessionRelUser);
876
877
        return $this;
878
    }
879
880
    public function removeGeneralCoach(User $user): self
881
    {
882
        $this->removeUserInSession(self::GENERAL_COACH, $user);
883
884
        return $this;
885
    }
886
887
    public function removeUserInSession(int $relationType, User $user): self
888
    {
889
        $criteria = Criteria::create()
890
            ->where(
891
                Criteria::expr()->eq('relationType', $relationType)
892
            )
893
            ->andWhere(
894
                Criteria::expr()->eq('user', $user)
895
            )
896
        ;
897
        $subscriptions = $this->users->matching($criteria);
898
899
        foreach ($subscriptions as $subscription) {
900
            $this->removeUserSubscription($subscription);
901
        }
902
903
        return $this;
904
    }
905
906
    public function removeUserSubscription(SessionRelUser $subscription): self
907
    {
908
        if ($this->hasUser($subscription)) {
909
            $subscription->setSession(null);
910
            $this->users->removeElement($subscription);
911
            $this->nbrUsers--;
912
        }
913
914
        return $this;
915
    }
916
917
    public function getCategory(): ?SessionCategory
918
    {
919
        return $this->category;
920
    }
921
922
    public function setCategory(?SessionCategory $category): self
923
    {
924
        $this->category = $category;
925
926
        return $this;
927
    }
928
929
    /**
930
     * Check if session is visible.
931
     */
932
    public function isActive(): bool
933
    {
934
        $now = new DateTime('now');
935
936
        return $now > $this->getAccessStartDate();
937
    }
938
939
    public function getAccessStartDate(): ?DateTime
940
    {
941
        return $this->accessStartDate;
942
    }
943
944
    public function setAccessStartDate(?DateTime $accessStartDate): self
945
    {
946
        $this->accessStartDate = $accessStartDate;
947
948
        return $this;
949
    }
950
951
    public function isActiveForStudent(): bool
952
    {
953
        $start = $this->getAccessStartDate();
954
        $end = $this->getAccessEndDate();
955
956
        return $this->compareDates($start, $end);
957
    }
958
959
    public function getAccessEndDate(): ?DateTime
960
    {
961
        return $this->accessEndDate;
962
    }
963
964
    public function setAccessEndDate(?DateTime $accessEndDate): self
965
    {
966
        $this->accessEndDate = $accessEndDate;
967
968
        return $this;
969
    }
970
971
    public function isActiveForCoach(): bool
972
    {
973
        $start = $this->getCoachAccessStartDate();
974
        $end = $this->getCoachAccessEndDate();
975
976
        return $this->compareDates($start, $end);
977
    }
978
979
    public function getCoachAccessStartDate(): ?DateTime
980
    {
981
        return $this->coachAccessStartDate;
982
    }
983
984
    public function setCoachAccessStartDate(?DateTime $coachAccessStartDate): self
985
    {
986
        $this->coachAccessStartDate = $coachAccessStartDate;
987
988
        return $this;
989
    }
990
991
    public function getCoachAccessEndDate(): ?DateTime
992
    {
993
        return $this->coachAccessEndDate;
994
    }
995
996
    public function setCoachAccessEndDate(?DateTime $coachAccessEndDate): self
997
    {
998
        $this->coachAccessEndDate = $coachAccessEndDate;
999
1000
        return $this;
1001
    }
1002
1003
    /**
1004
     * Compare the current date with start and end access dates.
1005
     * Either missing date is interpreted as no limit.
1006
     *
1007
     * @return bool whether now is between the session access start and end dates
1008
     */
1009
    public function isCurrentlyAccessible(): bool
1010
    {
1011
        $now = new DateTime();
1012
1013
        return (!$this->accessStartDate || $now >= $this->accessStartDate) && (!$this->accessEndDate || $now <= $this->accessEndDate);
1014
    }
1015
1016
    public function addCourse(Course $course): self
1017
    {
1018
        $sessionRelCourse = (new SessionRelCourse())->setCourse($course);
1019
        $this->addCourses($sessionRelCourse);
1020
1021
        return $this;
1022
    }
1023
1024
    /**
1025
     * Removes a course from this session.
1026
     *
1027
     * @param Course $course the course to remove from this session
1028
     *
1029
     * @return bool whether the course was actually found in this session and removed from it
1030
     */
1031
    public function removeCourse(Course $course): bool
1032
    {
1033
        $relCourse = $this->getCourseSubscription($course);
1034
        if (null !== $relCourse) {
1035
            $this->courses->removeElement($relCourse);
1036
            $this->setNbrCourses(\count($this->courses));
1037
1038
            return true;
1039
        }
1040
1041
        return false;
1042
    }
1043
1044
    /**
1045
     * Add a user course subscription.
1046
     * If user status in session is student, then increase number of course users.
1047
     * Status example: Session::STUDENT.
1048
     */
1049
    public function addUserInCourse(int $status, User $user, Course $course): ?SessionRelCourseRelUser
1050
    {
1051
        if ($this->hasUserInCourse($user, $course, $status)) {
1052
            return null;
1053
        }
1054
1055
        $userRelCourseRelSession = (new SessionRelCourseRelUser())
1056
            ->setCourse($course)
1057
            ->setUser($user)
1058
            ->setSession($this)
1059
            ->setStatus($status)
1060
        ;
1061
1062
        $this->addSessionRelCourseRelUser($userRelCourseRelSession);
1063
1064
        if (self::STUDENT === $status) {
1065
            $sessionCourse = $this->getCourseSubscription($course);
1066
            if ($sessionCourse) {
1067
                $sessionCourse->setNbrUsers($sessionCourse->getNbrUsers() + 1);
1068
            }
1069
        }
1070
1071
        return $userRelCourseRelSession;
1072
    }
1073
1074
    /**
1075
     * currentCourse is set in CidReqListener.
1076
     */
1077
    public function getCurrentCourse(): ?Course
1078
    {
1079
        return $this->currentCourse;
1080
    }
1081
1082
    /**
1083
     * currentCourse is set in CidReqListener.
1084
     */
1085
    public function setCurrentCourse(Course $course): self
1086
    {
1087
        // If the session is registered in the course session list.
1088
        $exists = $this->getCourses()
1089
            ->exists(
1090
                fn ($key, $element) => $course->getId() === $element->getCourse()->getId()
1091
            )
1092
        ;
1093
1094
        if ($exists) {
1095
            $this->currentCourse = $course;
1096
        }
1097
1098
        return $this;
1099
    }
1100
1101
    public function getSendSubscriptionNotification(): bool
1102
    {
1103
        return $this->sendSubscriptionNotification;
1104
    }
1105
1106
    public function setSendSubscriptionNotification(bool $sendNotification): self
1107
    {
1108
        $this->sendSubscriptionNotification = $sendNotification;
1109
1110
        return $this;
1111
    }
1112
1113
    /**
1114
     * Get user from course by status.
1115
     */
1116
    public function getSessionRelCourseRelUsersByStatus(Course $course, int $status): Collection
1117
    {
1118
        $criteria = Criteria::create()
1119
            ->where(
1120
                Criteria::expr()->eq('course', $course)
1121
            )
1122
            ->andWhere(
1123
                Criteria::expr()->eq('status', $status)
1124
            )
1125
        ;
1126
1127
        return $this->sessionRelCourseRelUsers->matching($criteria);
1128
    }
1129
1130
    public function getSessionRelCourseRelUserInCourse(Course $course): Collection
1131
    {
1132
        $criteria = Criteria::create()
1133
            ->where(
1134
                Criteria::expr()->eq('course', $course)
1135
            )
1136
        ;
1137
1138
        return $this->sessionRelCourseRelUsers->matching($criteria);
1139
    }
1140
1141
    public function getIssuedSkills(): Collection
1142
    {
1143
        return $this->issuedSkills;
1144
    }
1145
1146
    public function getCurrentUrl(): AccessUrl
1147
    {
1148
        return $this->currentUrl;
1149
    }
1150
1151
    public function setCurrentUrl(AccessUrl $url): self
1152
    {
1153
        $urlList = $this->getUrls();
1154
        foreach ($urlList as $item) {
1155
            if ($item->getUrl()->getId() === $url->getId()) {
1156
                $this->currentUrl = $url;
1157
1158
                break;
1159
            }
1160
        }
1161
1162
        return $this;
1163
    }
1164
1165
    /**
1166
     * @return Collection<int, EntityAccessUrlInterface>
1167
     */
1168
    public function getUrls(): Collection
1169
    {
1170
        return $this->urls;
1171
    }
1172
1173
    public function setUrls(Collection $urls): self
1174
    {
1175
        $this->urls = new ArrayCollection();
1176
        foreach ($urls as $url) {
1177
            $this->addUrls($url);
1178
        }
1179
1180
        return $this;
1181
    }
1182
1183
    public function addUrls(AccessUrlRelSession $url): self
1184
    {
1185
        $url->setSession($this);
1186
        $this->urls->add($url);
1187
1188
        return $this;
1189
    }
1190
1191
    public function addAccessUrl(?AccessUrl $url): self
1192
    {
1193
        $accessUrlRelSession = new AccessUrlRelSession();
1194
        $accessUrlRelSession->setUrl($url);
1195
        $accessUrlRelSession->setSession($this);
1196
        $this->addUrls($accessUrlRelSession);
1197
1198
        return $this;
1199
    }
1200
1201
    public function getPosition(): int
1202
    {
1203
        return $this->position;
1204
    }
1205
1206
    public function setPosition(int $position): self
1207
    {
1208
        $this->position = $position;
1209
1210
        return $this;
1211
    }
1212
1213
    public function getSessionAdmins(): ReadableCollection
1214
    {
1215
        return $this->getGeneralAdminsSubscriptions()
1216
            ->map(fn (SessionRelUser $subscription) => $subscription->getUser())
1217
        ;
1218
    }
1219
1220
    public function getGeneralAdminsSubscriptions(): Collection
1221
    {
1222
        $criteria = Criteria::create()->where(Criteria::expr()->eq('relationType', self::SESSION_ADMIN));
1223
1224
        return $this->users->matching($criteria);
1225
    }
1226
1227
    public function hasUserAsSessionAdmin(User $user): bool
1228
    {
1229
        $criteria = Criteria::create()
1230
            ->where(
1231
                Criteria::expr()->eq('relationType', self::SESSION_ADMIN)
1232
            )
1233
            ->andWhere(
1234
                Criteria::expr()->eq('user', $user)
1235
            )
1236
        ;
1237
1238
        return $this->users->matching($criteria)->count() > 0;
1239
    }
1240
1241
    public function addSessionAdmin(User $sessionAdmin): self
1242
    {
1243
        return $this->addUserInSession(self::SESSION_ADMIN, $sessionAdmin);
1244
    }
1245
1246
    public function getSkills(): Collection
1247
    {
1248
        return $this->skills;
1249
    }
1250
1251
    public function getResourceLinks(): Collection
1252
    {
1253
        return $this->resourceLinks;
1254
    }
1255
1256
    public function getImage(): ?Asset
1257
    {
1258
        return $this->image;
1259
    }
1260
1261
    public function setImage(?Asset $asset): self
1262
    {
1263
        $this->image = $asset;
1264
1265
        return $this;
1266
    }
1267
1268
    public function hasImage(): bool
1269
    {
1270
        return null !== $this->image;
1271
    }
1272
1273
    public function setImageUrl(?string $imageUrl): self
1274
    {
1275
        $this->imageUrl = $imageUrl;
1276
1277
        return $this;
1278
    }
1279
1280
    public function getImageUrl(): ?string
1281
    {
1282
        $image = $this->getImage();
1283
1284
        if ($image instanceof Asset) {
1285
            $category = $image->getCategory();
1286
            $filename = $image->getTitle();
1287
1288
            return \sprintf('/assets/%s/%s/%s', $category, $filename, $filename);
1289
        }
1290
1291
        return null;
1292
    }
1293
1294
    /**
1295
     * Check if $user is course coach in any course.
1296
     */
1297
    public function hasCoachInCourseList(User $user): bool
1298
    {
1299
        foreach ($this->courses as $sessionCourse) {
1300
            if ($this->hasCourseCoachInCourse($user, $sessionCourse->getCourse())) {
1301
                return true;
1302
            }
1303
        }
1304
1305
        return false;
1306
    }
1307
1308
    public function hasCourseCoachInCourse(User $user, ?Course $course = null): bool
1309
    {
1310
        if (null === $course) {
1311
            return false;
1312
        }
1313
1314
        return $this->hasUserInCourse($user, $course, self::COURSE_COACH);
1315
    }
1316
1317
    /**
1318
     * @param int $status if not set it will check if the user is registered
1319
     *                    with any status
1320
     */
1321
    public function hasUserInCourse(User $user, Course $course, ?int $status = null): bool
1322
    {
1323
        $relation = $this->getUserInCourse($user, $course, $status);
1324
1325
        return $relation->count() > 0;
1326
    }
1327
1328
    public function getUserInCourse(User $user, Course $course, ?int $status = null): Collection
1329
    {
1330
        $criteria = Criteria::create()
1331
            ->where(
1332
                Criteria::expr()->eq('course', $course)
1333
            )
1334
            ->andWhere(
1335
                Criteria::expr()->eq('user', $user)
1336
            )
1337
        ;
1338
1339
        if (null !== $status) {
1340
            $criteria->andWhere(Criteria::expr()->eq('status', $status));
1341
        }
1342
1343
        return $this->getSessionRelCourseRelUsers()->matching($criteria);
1344
    }
1345
1346
    /**
1347
     * Check if $user is student in any course.
1348
     */
1349
    public function hasStudentInCourseList(User $user): bool
1350
    {
1351
        foreach ($this->courses as $sessionCourse) {
1352
            if ($this->hasStudentInCourse($user, $sessionCourse->getCourse())) {
1353
                return true;
1354
            }
1355
        }
1356
1357
        return false;
1358
    }
1359
1360
    public function hasStudentInCourse(User $user, Course $course): bool
1361
    {
1362
        return $this->hasUserInCourse($user, $course, self::STUDENT);
1363
    }
1364
1365
    protected function compareDates(?DateTime $start, ?DateTime $end = null): bool
1366
    {
1367
        $now = new DateTime('now');
1368
1369
        if (!empty($start) && !empty($end)) {
1370
            return $now >= $start && $now <= $end;
1371
        }
1372
1373
        if (!empty($start)) {
1374
            return $now >= $start;
1375
        }
1376
1377
        return !empty($end) && $now <= $end;
1378
    }
1379
1380
    /**
1381
     * @return Collection<int, SessionRelCourseRelUser>
1382
     */
1383
    public function getCourseCoaches(): Collection
1384
    {
1385
        return $this->getCourseCoachesSubscriptions()
1386
            ->map(fn (SessionRelCourseRelUser $subscription) => $subscription->getUser())
1387
        ;
1388
    }
1389
1390
    /**
1391
     * @return Collection<int, SessionRelCourseRelUser>
1392
     */
1393
    #[Groups(['session:basic', 'user_subscriptions:sessions'])]
1394
    public function getCourseCoachesSubscriptions(): Collection
1395
    {
1396
        return $this->getAllUsersFromCourse(self::COURSE_COACH);
1397
    }
1398
1399
    public function isAvailableByDurationForUser(User $user): bool
1400
    {
1401
        $duration = $this->duration * 24 * 60 * 60;
1402
1403
        if (0 === $user->getTrackECourseAccess()->count()) {
1404
            return true;
1405
        }
1406
1407
        $trackECourseAccess = $user->getFirstAccessToSession($this);
1408
1409
        $firstAccess = $trackECourseAccess
1410
            ? $trackECourseAccess->getLoginCourseDate()->getTimestamp()
1411
            : 0;
1412
1413
        $userDurationData = $user->getSubscriptionToSession($this);
1414
1415
        $userDuration = $userDurationData
1416
            ? ($userDurationData->getDuration() * 24 * 60 * 60)
1417
            : 0;
1418
1419
        $totalDuration = $firstAccess + $duration + $userDuration;
1420
        $currentTime = time();
1421
1422
        return $totalDuration > $currentTime;
1423
    }
1424
1425
    public function getDaysLeftByUser(User $user): int
1426
    {
1427
        $userSessionSubscription = $user->getSubscriptionToSession($this);
1428
1429
        $duration = $this->duration;
1430
1431
        if ($userSessionSubscription) {
1432
            $duration += $userSessionSubscription->getDuration();
1433
        }
1434
1435
        $courseAccess = $user->getFirstAccessToSession($this);
1436
1437
        if (!$courseAccess) {
1438
            return $duration;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $duration 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...
1439
        }
1440
1441
        $endDateInSeconds = $courseAccess->getLoginCourseDate()->getTimestamp() + $duration * 24 * 60 * 60;
1442
        $currentTime = time();
1443
1444
        return (int) round(($endDateInSeconds - $currentTime) / 60 / 60 / 24);
1445
    }
1446
1447
    private function getAccessVisibilityByDuration(User $user): int
1448
    {
1449
        // Session duration per student.
1450
        if ($this->getDuration() > 0) {
1451
            if ($this->hasCoach($user)) {
1452
                return self::AVAILABLE;
1453
            }
1454
1455
            $duration = $this->getDuration() * 24 * 60 * 60;
1456
            $courseAccess = $user->getFirstAccessToSession($this);
1457
1458
            // If there is a session duration but there is no previous
1459
            // access by the user, then the session is still available
1460
            if (!$courseAccess) {
1461
                return self::AVAILABLE;
1462
            }
1463
1464
            $currentTime = time();
1465
            $firstAccess = $courseAccess->getLoginCourseDate()->getTimestamp();
1466
            $userSessionSubscription = $user->getSubscriptionToSession($this);
1467
            $userDuration = $userSessionSubscription
1468
                ? $userSessionSubscription->getDuration() * 24 * 60 * 60
1469
                : 0;
1470
1471
            $totalDuration = $firstAccess + $duration + $userDuration;
1472
1473
            return $totalDuration > $currentTime ? self::AVAILABLE : $this->visibility;
1474
        }
1475
1476
        return self::AVAILABLE;
1477
    }
1478
1479
    /**
1480
     * Checks whether the user is a course or session coach.
1481
     */
1482
    public function hasCoach(User $user): bool
1483
    {
1484
        return $this->hasUserAsGeneralCoach($user) || $this->hasCoachInCourseList($user);
1485
    }
1486
1487
    private function getAcessVisibilityByDates(User $user): int
1488
    {
1489
        $now = new DateTime();
1490
1491
        $userIsCoach = $this->hasCoach($user);
1492
1493
        $sessionEndDate = $userIsCoach && $this->coachAccessEndDate
1494
            ? $this->coachAccessEndDate
1495
            : $this->accessEndDate;
1496
1497
        if (!$userIsCoach && $this->accessStartDate && $now < $this->accessStartDate) {
1498
            return self::LIST_ONLY;
1499
        }
1500
1501
        if ($sessionEndDate) {
1502
            return $now <= $sessionEndDate ? self::AVAILABLE : $this->visibility;
1503
        }
1504
1505
        return self::AVAILABLE;
1506
    }
1507
1508
    public function setAccessVisibilityByUser(User $user, bool $ignoreVisibilityForAdmins = true): int
1509
    {
1510
        if (($user->isAdmin() || $user->isSuperAdmin()) && $ignoreVisibilityForAdmins) {
1511
            $this->accessVisibility = self::AVAILABLE;
1512
        } elseif (!$this->getAccessStartDate() && !$this->getAccessEndDate()) {
1513
            // I don't care the session visibility.
1514
            $this->accessVisibility = $this->getAccessVisibilityByDuration($user);
1515
        } else {
1516
            $this->accessVisibility = $this->getAcessVisibilityByDates($user);
1517
        }
1518
1519
        return $this->accessVisibility;
1520
    }
1521
1522
    public function getAccessVisibility(): int
1523
    {
1524
        if (0 === $this->accessVisibility) {
1525
            throw new LogicException('Access visibility by user is not set');
1526
        }
1527
1528
        return $this->accessVisibility;
1529
    }
1530
1531
    public function getClosedOrHiddenCourses(): Collection
1532
    {
1533
        $closedVisibilities = [
1534
            Course::CLOSED,
1535
            Course::HIDDEN,
1536
        ];
1537
1538
        return $this->courses->filter(fn (SessionRelCourse $sessionRelCourse) => \in_array(
1539
            $sessionRelCourse->getCourse()->getVisibility(),
1540
            $closedVisibilities
1541
        ));
1542
    }
1543
1544
    public function getParentId(): ?int
1545
    {
1546
        return $this->parentId;
1547
    }
1548
1549
    public function setParentId(?int $parentId): self
1550
    {
1551
        $this->parentId = $parentId;
1552
1553
        return $this;
1554
    }
1555
1556
    public function getDaysToReinscription(): ?int
1557
    {
1558
        return $this->daysToReinscription;
1559
    }
1560
1561
    public function setDaysToReinscription(?int $daysToReinscription): self
1562
    {
1563
        $this->daysToReinscription = $daysToReinscription ?: null;
1564
1565
        return $this;
1566
    }
1567
1568
    public function getLastRepetition(): bool
1569
    {
1570
        return $this->lastRepetition;
1571
    }
1572
1573
    public function setLastRepetition(bool $lastRepetition): self
1574
    {
1575
        $this->lastRepetition = $lastRepetition;
1576
1577
        return $this;
1578
    }
1579
1580
    public function getDaysToNewRepetition(): ?int
1581
    {
1582
        return $this->daysToNewRepetition;
1583
    }
1584
1585
    public function setDaysToNewRepetition(?int $daysToNewRepetition): self
1586
    {
1587
        $this->daysToNewRepetition = $daysToNewRepetition ?: null;
1588
1589
        return $this;
1590
    }
1591
1592
    public function getNotifyBoss(): bool
1593
    {
1594
        return $this->notifyBoss;
1595
    }
1596
1597
    public function setNotifyBoss(bool $notifyBoss): self
1598
    {
1599
        $this->notifyBoss = $notifyBoss;
1600
1601
        return $this;
1602
    }
1603
1604
    public function getValidityInDays(): ?int
1605
    {
1606
        return $this->validityInDays;
1607
    }
1608
1609
    public function setValidityInDays(?int $validityInDays): self
1610
    {
1611
        $this->validityInDays = $validityInDays ?: null;
1612
1613
        return $this;
1614
    }
1615
}
1616