Passed
Push — 1.11.x ( b08d33...fc80cf )
by Angel Fernando Quiroz
08:20 queued 14s
created

Meeting::setSignAttendance()   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
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\PluginBundle\Zoom;
6
7
use Chamilo\CoreBundle\Entity\Course;
8
use Chamilo\CoreBundle\Entity\CourseRelUser;
9
use Chamilo\CoreBundle\Entity\Session;
10
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
11
use Chamilo\CoreBundle\Entity\SysAnnouncement;
12
use Chamilo\CourseBundle\Entity\CGroupInfo;
13
use Chamilo\PluginBundle\Zoom\API\BaseMeetingTrait;
14
use Chamilo\PluginBundle\Zoom\API\MeetingInfoGet;
15
use Chamilo\PluginBundle\Zoom\API\MeetingListItem;
16
use Chamilo\PluginBundle\Zoom\API\MeetingSettings;
17
use Chamilo\UserBundle\Entity\User;
18
use Database;
19
use DateInterval;
20
use DateTime;
21
use DateTimeZone;
22
use Doctrine\Common\Collections\ArrayCollection;
23
use Doctrine\Common\Collections\Criteria;
24
use Doctrine\ORM\Mapping as ORM;
25
use Exception;
26
27
/**
28
 * Class Meeting.
29
 *
30
 * @ORM\Entity(repositoryClass="Chamilo\PluginBundle\Zoom\MeetingRepository")
31
 * @ORM\Table(
32
 *     name="plugin_zoom_meeting",
33
 *     indexes={
34
 *         @ORM\Index(name="user_id_index", columns={"user_id"}),
35
 *         @ORM\Index(name="course_id_index", columns={"course_id"}),
36
 *         @ORM\Index(name="session_id_index", columns={"session_id"})
37
 *     }
38
 * )
39
 * @ORM\HasLifecycleCallbacks
40
 * @ORM\InheritanceType("SINGLE_TABLE")
41
 * @ORM\DiscriminatorColumn(name="type", type="string")
42
 * @ORM\DiscriminatorMap({"meeting" = "Chamilo\PluginBundle\Zoom\Meeting", "webinar" = "Chamilo\PluginBundle\Zoom\Webinar"})
43
 */
44
class Meeting
45
{
46
    /** @var string meeting type name */
47
    public $typeName;
48
49
    /** @var DateTime meeting start time as a DateTime instance */
50
    public $startDateTime;
51
52
    /** @var string meeting formatted start time */
53
    public $formattedStartTime;
54
55
    /** @var DateInterval meeting duration as a DateInterval instance */
56
    public $durationInterval;
57
58
    /** @var string meeting formatted duration */
59
    public $formattedDuration;
60
61
    /** @var string */
62
    public $statusName;
63
64
    /**
65
     * @var int
66
     * @ORM\Column(type="integer", name="id")
67
     * @ORM\Id
68
     * @ORM\GeneratedValue()
69
     */
70
    protected $id;
71
72
    /**
73
     * @var int the remote zoom meeting identifier
74
     * @ORM\Column(name="meeting_id", type="string")
75
     */
76
    protected $meetingId;
77
78
    /**
79
     * @var User
80
     * @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User")
81
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
82
     */
83
    protected $user;
84
85
    /**
86
     * @var Course
87
     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course")
88
     * @ORM\JoinColumn(name="course_id", referencedColumnName="id", nullable=true)
89
     */
90
    protected $course;
91
92
    /**
93
     * @var CGroupInfo
94
     * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CGroupInfo")
95
     * @ORM\JoinColumn(name="group_id", referencedColumnName="iid", nullable=true)
96
     */
97
    protected $group;
98
99
    /**
100
     * @var Session
101
     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session")
102
     * @ORM\JoinColumn(name="session_id", referencedColumnName="id", nullable=true)
103
     */
104
    protected $session;
105
106
    /**
107
     * @var string
108
     * @ORM\Column(type="text", name="meeting_list_item_json", nullable=true)
109
     */
110
    protected $meetingListItemJson;
111
112
    /**
113
     * @var string
114
     * @ORM\Column(type="text", name="meeting_info_get_json", nullable=true)
115
     */
116
    protected $meetingInfoGetJson;
117
118
    /**
119
     * @var bool
120
     *
121
     * @ORM\Column(type="boolean", name="sign_attendance")
122
     */
123
    protected $signAttendance;
124
125
    /**
126
     * @var string|null
127
     *
128
     * @ORM\Column(type="text", name="reason_to_sign_attendance", nullable=true)
129
     */
130
    protected $reasonToSignAttendance;
131
132
    /** @var MeetingListItem */
133
    protected $meetingListItem;
134
135
    /** @var MeetingInfoGet */
136
    protected $meetingInfoGet;
137
138
    /**
139
     * @var MeetingActivity[]|ArrayCollection
140
     * @ORM\OrderBy({"createdAt" = "DESC"})
141
     * @ORM\OneToMany(targetEntity="MeetingActivity", mappedBy="meeting", cascade={"persist", "remove"})
142
     */
143
    protected $activities;
144
145
    /**
146
     * @var Registrant[]|ArrayCollection
147
     *
148
     * @ORM\OneToMany(targetEntity="Registrant", mappedBy="meeting", cascade={"persist", "remove"})
149
     */
150
    protected $registrants;
151
152
    /**
153
     * @var Recording[]|ArrayCollection
154
     *
155
     * @ORM\OneToMany(targetEntity="Recording", mappedBy="meeting", cascade={"persist"}, orphanRemoval=true)
156
     */
157
    protected $recordings;
158
159
    /**
160
     * @var string|null
161
     *
162
     * @ORM\Column(type="string", name="account_email", nullable=true)
163
     */
164
    protected $accountEmail;
165
166
    /**
167
     * @var SysAnnouncement|null
168
     *
169
     * @ORM\OneToOne(targetEntity="Chamilo\CoreBundle\Entity\SysAnnouncement")
170
     * @ORM\JoinColumn(name="sys_announcement_id", referencedColumnName="id", onDelete="SET NULL")
171
     */
172
    protected $sysAnnouncement;
173
174
    public function __construct()
175
    {
176
        $this->registrants = new ArrayCollection();
177
        $this->recordings = new ArrayCollection();
178
        $this->activities = new ArrayCollection();
179
        $this->signAttendance = false;
180
        $this->sysAnnouncement = null;
181
    }
182
183
    /**
184
     * @return string
185
     */
186
    public function __toString()
187
    {
188
        return sprintf('Meeting %d', $this->id);
189
    }
190
191
    /**
192
     * @return int
193
     */
194
    public function getId()
195
    {
196
        return $this->id;
197
    }
198
199
    /**
200
     * @return int
201
     */
202
    public function getMeetingId()
203
    {
204
        return $this->meetingId;
205
    }
206
207
    /**
208
     * @param int $meetingId
209
     *
210
     * @return Meeting
211
     */
212
    public function setMeetingId($meetingId)
213
    {
214
        $this->meetingId = $meetingId;
215
216
        return $this;
217
    }
218
219
    /**
220
     * @return User
221
     */
222
    public function getUser()
223
    {
224
        return $this->user;
225
    }
226
227
    /**
228
     * @return Course
229
     */
230
    public function getCourse()
231
    {
232
        return $this->course;
233
    }
234
235
    /**
236
     * @return Session
237
     */
238
    public function getSession()
239
    {
240
        return $this->session;
241
    }
242
243
    /**
244
     * @return Registrant[]|ArrayCollection
245
     */
246
    public function getRegistrants()
247
    {
248
        return $this->registrants->filter(function (Registrant $registrant) {
249
            return !$registrant instanceof Presenter;
250
        });
251
    }
252
253
    /**
254
     * @return ArrayCollection<int, Presenter>
255
     */
256
    public function getPresenters(): ArrayCollection
257
    {
258
        return $this->registrants->filter(function (Registrant $registrant) {
259
            return $registrant instanceof Presenter;
260
        });
261
    }
262
263
    public function hasUserAsPresenter(User $user): bool
264
    {
265
        $presenters = $this->getPresenters();
266
267
        $criteria = Criteria::create();
268
        $criteria->where(
269
            Criteria::expr()->eq('user', $user)
270
        );
271
272
        return $presenters->matching($criteria)->count() > 0;
273
    }
274
275
    /**
276
     * @return Recording[]|ArrayCollection
277
     */
278
    public function getRecordings()
279
    {
280
        return $this->recordings;
281
    }
282
283
    /**
284
     * @return MeetingActivity[]|ArrayCollection
285
     */
286
    public function getActivities()
287
    {
288
        return $this->activities;
289
    }
290
291
    public function addActivity(MeetingActivity $activity)
292
    {
293
        $activity->setMeeting($this);
294
        $this->activities[] = $activity;
295
    }
296
297
    /**
298
     * @param MeetingActivity[]|ArrayCollection $activities
299
     *
300
     * @return Meeting
301
     */
302
    public function setActivities($activities)
303
    {
304
        $this->activities = $activities;
305
306
        return $this;
307
    }
308
309
    /**
310
     * @ORM\PostLoad
311
     *
312
     * @throws Exception
313
     */
314
    public function postLoad()
315
    {
316
        if (null !== $this->meetingListItemJson) {
317
            $this->meetingListItem = MeetingListItem::fromJson($this->meetingListItemJson);
318
        }
319
        if (null !== $this->meetingInfoGetJson) {
320
            $this->meetingInfoGet = MeetingInfoGet::fromJson($this->meetingInfoGetJson);
321
        }
322
        $this->initializeDisplayableProperties();
323
    }
324
325
    /**
326
     * @ORM\PostUpdate
327
     *
328
     * @throws Exception
329
     */
330
    public function postUpdate()
331
    {
332
        $this->initializeDisplayableProperties();
333
    }
334
335
    /**
336
     * @ORM\PreFlush
337
     */
338
    public function preFlush()
339
    {
340
        if (null !== $this->meetingListItem) {
341
            $this->meetingListItemJson = json_encode($this->meetingListItem);
342
        }
343
        if (null !== $this->meetingInfoGet) {
344
            $this->meetingInfoGetJson = json_encode($this->meetingInfoGet);
345
        }
346
    }
347
348
    /**
349
     * @return MeetingListItem
350
     */
351
    public function getMeetingListItem()
352
    {
353
        return $this->meetingListItem;
354
    }
355
356
    /**
357
     * @return MeetingInfoGet
358
     */
359
    public function getMeetingInfoGet()
360
    {
361
        return $this->meetingInfoGet;
362
    }
363
364
    /**
365
     * @param User $user
366
     *
367
     * @return $this
368
     */
369
    public function setUser($user)
370
    {
371
        $this->user = $user;
372
373
        return $this;
374
    }
375
376
    /**
377
     * @param Course $course
378
     *
379
     * @return $this
380
     */
381
    public function setCourse($course)
382
    {
383
        $this->course = $course;
384
385
        return $this;
386
    }
387
388
    /**
389
     * @param Session $session
390
     *
391
     * @return $this
392
     */
393
    public function setSession($session)
394
    {
395
        $this->session = $session;
396
397
        return $this;
398
    }
399
400
    /**
401
     * @return CGroupInfo
402
     */
403
    public function getGroup()
404
    {
405
        return $this->group;
406
    }
407
408
    /**
409
     * @param CGroupInfo $group
410
     *
411
     * @return Meeting
412
     */
413
    public function setGroup($group)
414
    {
415
        $this->group = $group;
416
417
        return $this;
418
    }
419
420
    /**
421
     * @param MeetingListItem $meetingListItem
422
     *
423
     * @throws Exception
424
     *
425
     * @return Meeting
426
     */
427
    public function setMeetingListItem($meetingListItem)
428
    {
429
        if (null === $this->meetingId) {
430
            $this->meetingId = $meetingListItem->id;
0 ignored issues
show
Documentation Bug introduced by
The property $meetingId was declared of type integer, but $meetingListItem->id is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
431
        } elseif ($this->meetingId != $meetingListItem->id) {
432
            throw new Exception('the Meeting identifier differs from the MeetingListItem identifier');
433
        }
434
        $this->meetingListItem = $meetingListItem;
435
436
        return $this;
437
    }
438
439
    /**
440
     * @param MeetingInfoGet|BaseMeetingTrait $meetingInfoGet
441
     *
442
     * @throws Exception
443
     *
444
     * @return Meeting
445
     */
446
    public function setMeetingInfoGet($meetingInfoGet)
447
    {
448
        if (null === $this->meetingId) {
449
            $this->meetingId = $meetingInfoGet->id;
0 ignored issues
show
Documentation Bug introduced by
The property $meetingId was declared of type integer, but $meetingInfoGet->id is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
450
        } elseif ($this->meetingId != $meetingInfoGet->id) {
451
            throw new Exception('the Meeting identifier differs from the MeetingInfoGet identifier');
452
        }
453
        $this->meetingInfoGet = $meetingInfoGet;
454
        $this->initializeDisplayableProperties();
455
456
        return $this;
457
    }
458
459
    /**
460
     * @return bool
461
     */
462
    public function isCourseMeeting()
463
    {
464
        return null !== $this->course;
465
    }
466
467
    /**
468
     * @return bool
469
     */
470
    public function isCourseGroupMeeting()
471
    {
472
        return null !== $this->course && null !== $this->group;
473
    }
474
475
    /**
476
     * @return bool
477
     */
478
    public function isUserMeeting()
479
    {
480
        return null !== $this->user && null === $this->course;
481
    }
482
483
    /**
484
     * @return bool
485
     */
486
    public function isGlobalMeeting()
487
    {
488
        return null === $this->user && null === $this->course;
489
    }
490
491
    public function setStatus($status)
492
    {
493
        $this->meetingInfoGet->status = $status;
494
    }
495
496
    /**
497
     * Builds the list of users that can register into this meeting.
498
     * Zoom requires an email address, therefore users without an email address are excluded from the list.
499
     *
500
     * @return User[] the list of users
501
     */
502
    public function getRegistrableUsers()
503
    {
504
        $users = [];
505
        if (!$this->isCourseMeeting()) {
506
            $criteria = ['active' => true];
507
            $users = Database::getManager()->getRepository('ChamiloUserBundle:User')->findBy($criteria);
508
        } elseif (null === $this->session) {
509
            if (null !== $this->course) {
510
                /** @var CourseRelUser $courseRelUser */
511
                foreach ($this->course->getUsers() as $courseRelUser) {
512
                    $users[] = $courseRelUser->getUser();
513
                }
514
            }
515
        } else {
516
            if (null !== $this->course) {
517
                $subscriptions = $this->session->getUserCourseSubscriptionsByStatus($this->course, Session::STUDENT);
518
                if ($subscriptions) {
519
                    /** @var SessionRelCourseRelUser $sessionCourseUser */
520
                    foreach ($subscriptions as $sessionCourseUser) {
521
                        $users[] = $sessionCourseUser->getUser();
522
                    }
523
                }
524
            }
525
        }
526
527
        $activeUsersWithEmail = [];
528
        foreach ($users as $user) {
529
            if ($user->isActive() && !empty($user->getEmail())) {
530
                $activeUsersWithEmail[] = $user;
531
            }
532
        }
533
534
        return $activeUsersWithEmail;
535
    }
536
537
    /**
538
     * @return bool
539
     */
540
    public function requiresDateAndDuration()
541
    {
542
        return MeetingInfoGet::TYPE_SCHEDULED === $this->meetingInfoGet->type
543
            || MeetingInfoGet::TYPE_RECURRING_WITH_FIXED_TIME === $this->meetingInfoGet->type;
544
    }
545
546
    public function requiresRegistration(): bool
547
    {
548
        return true; //MeetingSettings::APPROVAL_TYPE_AUTOMATICALLY_APPROVE === $this->meetingInfoGet->settings->approval_type;
549
        /*return
550
            MeetingSettings::APPROVAL_TYPE_NO_REGISTRATION_REQUIRED != $this->meetingInfoGet->settings->approval_type;*/
551
    }
552
553
    /**
554
     * @return bool
555
     */
556
    public function hasCloudAutoRecordingEnabled()
557
    {
558
        return \ZoomPlugin::RECORDING_TYPE_NONE !== $this->meetingInfoGet->settings->auto_recording;
559
    }
560
561
    public function getRegistrantByUser(User $user): ?Registrant
562
    {
563
        $criteria = Criteria::create()
564
            ->where(
565
                Criteria::expr()->eq('user', $user)
566
            )
567
        ;
568
569
        return $this->registrants->matching($criteria)->first() ?: null;
570
    }
571
572
    /**
573
     * Generates a short presentation of the meeting for the future participant.
574
     * To be displayed above the "Enter meeting" link.
575
     *
576
     * @return string
577
     */
578
    public function getIntroduction()
579
    {
580
        $introduction = sprintf('<h1>%s</h1>', $this->getTopic()).PHP_EOL;
581
        if (!$this->isGlobalMeeting()) {
582
            if (!empty($this->formattedStartTime)) {
583
                $introduction .= $this->formattedStartTime;
584
                if (!empty($this->formattedDuration)) {
585
                    $introduction .= ' ('.$this->formattedDuration.')';
586
                }
587
                $introduction .= PHP_EOL;
588
            }
589
        }
590
        if ($this->user) {
591
            $introduction .= sprintf('<p>%s</p>', $this->user->getFullname()).PHP_EOL;
592
        } elseif ($this->isCourseMeeting()) {
593
            if (null === $this->session) {
594
                $introduction .= sprintf('<p class="main">%s</p>', $this->course).PHP_EOL;
595
            } else {
596
                $introduction .= sprintf('<p class="main">%s (%s)</p>', $this->course, $this->session).PHP_EOL;
597
            }
598
        }
599
600
        if (!empty($this->getAgenda())) {
601
            $introduction .= sprintf('<p>%s</p>', $this->getAgenda()).PHP_EOL;
602
        }
603
604
        return $introduction;
605
    }
606
607
    public function isSignAttendance(): bool
608
    {
609
        return $this->signAttendance;
610
    }
611
612
    public function setSignAttendance(bool $signAttendance): Meeting
613
    {
614
        $this->signAttendance = $signAttendance;
615
616
        return $this;
617
    }
618
619
    public function getAccountEmail(): ?string
620
    {
621
        return $this->accountEmail;
622
    }
623
624
    public function setAccountEmail(?string $accountEmail): self
625
    {
626
        $this->accountEmail = $accountEmail;
627
628
        return $this;
629
    }
630
631
    public function getReasonToSignAttendance(): ?string
632
    {
633
        return $this->reasonToSignAttendance;
634
    }
635
636
    public function setReasonToSignAttendance(string $reasonToSignAttendance): Meeting
637
    {
638
        $this->reasonToSignAttendance = $reasonToSignAttendance;
639
640
        return $this;
641
    }
642
643
    public function getTopic(): string
644
    {
645
        return $this->meetingInfoGet->topic;
646
    }
647
648
    public function getAgenda(): ?string
649
    {
650
        return $this->meetingInfoGet->agenda;
651
    }
652
653
    public function getSysAnnouncement(): ?SysAnnouncement
654
    {
655
        return $this->sysAnnouncement;
656
    }
657
658
    public function setSysAnnouncement(?SysAnnouncement $sysAnnouncement): Meeting
659
    {
660
        $this->sysAnnouncement = $sysAnnouncement;
661
662
        return $this;
663
    }
664
665
    /**
666
     * @throws Exception on unexpected start_time or duration
667
     */
668
    protected function initializeDisplayableProperties()
669
    {
670
        $zoomPlugin = new \ZoomPlugin();
671
672
        $typeList = [
673
            API\Meeting::TYPE_INSTANT => $zoomPlugin->get_lang('InstantMeeting'),
674
            API\Meeting::TYPE_SCHEDULED => $zoomPlugin->get_lang('ScheduledMeeting'),
675
            API\Meeting::TYPE_RECURRING_WITH_NO_FIXED_TIME => $zoomPlugin->get_lang('RecurringWithNoFixedTime'),
676
            API\Meeting::TYPE_RECURRING_WITH_FIXED_TIME => $zoomPlugin->get_lang('RecurringWithFixedTime'),
677
        ];
678
        $this->typeName = $typeList[$this->meetingInfoGet->type];
679
680
        if (property_exists($this, 'status')) {
681
            $statusList = [
682
                'waiting' => $zoomPlugin->get_lang('Waiting'),
683
                'started' => $zoomPlugin->get_lang('Started'),
684
                'finished' => $zoomPlugin->get_lang('Finished'),
685
            ];
686
            $this->statusName = $statusList[$this->meetingInfoGet->status];
687
        }
688
        $this->startDateTime = null;
689
        $this->formattedStartTime = '';
690
        $this->durationInterval = null;
691
        $this->formattedDuration = '';
692
        if (!empty($this->meetingInfoGet->start_time)) {
693
            $this->startDateTime = new DateTime($this->meetingInfoGet->start_time);
694
            $this->startDateTime->setTimezone(new DateTimeZone(api_get_timezone()));
695
            $this->formattedStartTime = $this->startDateTime->format('Y-m-d H:i');
696
        }
697
698
        if (!empty($this->meetingInfoGet->duration)) {
699
            $now = new DateTime();
700
            $later = new DateTime();
701
            $later->add(new DateInterval('PT'.$this->meetingInfoGet->duration.'M'));
702
            $this->durationInterval = $now->diff($later);
703
            $this->formattedDuration = $this->durationInterval->format($zoomPlugin->get_lang('DurationFormat'));
704
        }
705
    }
706
}
707