Passed
Push — master ( 689c60...4980bd )
by Julito
09:36
created

Session::getSessionRelCourseByUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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