Passed
Push — master ( fad34a...39075e )
by Julito
16:30
created

Session::setSessionRelCourseRelUsers()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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