Passed
Push — master ( 8f07b0...3fcb32 )
by Julito
15:06
created

Session::isCurrentlyAccessible()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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