Passed
Push — master ( 12773c...b56fa5 )
by Julito
09:46
created

Session::setCoachAccessStartDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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