Passed
Pull Request — 1.11.x (#4160)
by Angel Fernando Quiroz
07:54
created

Meeting::getRegistrant()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 1
nc 1
nop 1
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\CourseBundle\Entity\CGroupInfo;
12
use Chamilo\PluginBundle\Zoom\API\BaseMeetingTrait;
13
use Chamilo\PluginBundle\Zoom\API\MeetingInfoGet;
14
use Chamilo\PluginBundle\Zoom\API\MeetingListItem;
15
use Chamilo\PluginBundle\Zoom\API\MeetingSettings;
16
use Chamilo\UserBundle\Entity\User;
17
use Database;
18
use DateInterval;
19
use DateTime;
20
use DateTimeZone;
21
use Doctrine\Common\Collections\ArrayCollection;
22
use Doctrine\Common\Collections\Criteria;
23
use Doctrine\ORM\Mapping as ORM;
24
use Exception;
25
26
/**
27
 * Class Meeting.
28
 *
29
 * @ORM\Entity(repositoryClass="Chamilo\PluginBundle\Zoom\MeetingRepository")
30
 * @ORM\Table(
31
 *     name="plugin_zoom_meeting",
32
 *     indexes={
33
 *         @ORM\Index(name="user_id_index", columns={"user_id"}),
34
 *         @ORM\Index(name="course_id_index", columns={"course_id"}),
35
 *         @ORM\Index(name="session_id_index", columns={"session_id"})
36
 *     }
37
 * )
38
 * @ORM\HasLifecycleCallbacks
39
 * @ORM\InheritanceType("SINGLE_TABLE")
40
 * @ORM\DiscriminatorColumn(name="type", type="string")
41
 * @ORM\DiscriminatorMap({"meeting" = "Chamilo\PluginBundle\Zoom\Meeting", "webinar" = "Chamilo\PluginBundle\Zoom\Webinar"})
42
 */
43
class Meeting
44
{
45
    /** @var string meeting type name */
46
    public $typeName;
47
48
    /** @var DateTime meeting start time as a DateTime instance */
49
    public $startDateTime;
50
51
    /** @var string meeting formatted start time */
52
    public $formattedStartTime;
53
54
    /** @var DateInterval meeting duration as a DateInterval instance */
55
    public $durationInterval;
56
57
    /** @var string meeting formatted duration */
58
    public $formattedDuration;
59
60
    /** @var string */
61
    public $statusName;
62
63
    /**
64
     * @var int
65
     * @ORM\Column(type="integer", name="id")
66
     * @ORM\Id
67
     * @ORM\GeneratedValue()
68
     */
69
    protected $id;
70
71
    /**
72
     * @var int the remote zoom meeting identifier
73
     * @ORM\Column(name="meeting_id", type="string")
74
     */
75
    protected $meetingId;
76
77
    /**
78
     * @var User
79
     * @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User")
80
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
81
     */
82
    protected $user;
83
84
    /**
85
     * @var Course
86
     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course")
87
     * @ORM\JoinColumn(name="course_id", referencedColumnName="id", nullable=true)
88
     */
89
    protected $course;
90
91
    /**
92
     * @var CGroupInfo
93
     * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CGroupInfo")
94
     * @ORM\JoinColumn(name="group_id", referencedColumnName="iid", nullable=true)
95
     */
96
    protected $group;
97
98
    /**
99
     * @var Session
100
     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session")
101
     * @ORM\JoinColumn(name="session_id", referencedColumnName="id", nullable=true)
102
     */
103
    protected $session;
104
105
    /**
106
     * @var string
107
     * @ORM\Column(type="text", name="meeting_list_item_json", nullable=true)
108
     */
109
    protected $meetingListItemJson;
110
111
    /**
112
     * @var string
113
     * @ORM\Column(type="text", name="meeting_info_get_json", nullable=true)
114
     */
115
    protected $meetingInfoGetJson;
116
117
    /**
118
     * @var bool
119
     *
120
     * @ORM\Column(type="boolean", name="sign_attendance")
121
     */
122
    protected $signAttendance;
123
124
    /**
125
     * @var string|null
126
     *
127
     * @ORM\Column(type="text", name="reason_to_sign_attendance", nullable=true)
128
     */
129
    protected $reasonToSignAttendance;
130
131
    /** @var MeetingListItem */
132
    protected $meetingListItem;
133
134
    /** @var MeetingInfoGet */
135
    protected $meetingInfoGet;
136
137
    /**
138
     * @var MeetingActivity[]|ArrayCollection
139
     * @ORM\OrderBy({"createdAt" = "DESC"})
140
     * @ORM\OneToMany(targetEntity="MeetingActivity", mappedBy="meeting", cascade={"persist", "remove"})
141
     */
142
    protected $activities;
143
144
    /**
145
     * @var Registrant[]|ArrayCollection
146
     *
147
     * @ORM\OneToMany(targetEntity="Registrant", mappedBy="meeting", cascade={"persist", "remove"})
148
     */
149
    protected $registrants;
150
151
    /**
152
     * @var Recording[]|ArrayCollection
153
     *
154
     * @ORM\OneToMany(targetEntity="Recording", mappedBy="meeting", cascade={"persist"}, orphanRemoval=true)
155
     */
156
    protected $recordings;
157
158
    /**
159
     * @var string|null
160
     *
161
     * @ORM\Column(type="string", name="account_email", nullable=true)
162
     */
163
    protected $accountEmail;
164
165
    public function __construct()
166
    {
167
        $this->registrants = new ArrayCollection();
168
        $this->recordings = new ArrayCollection();
169
        $this->activities = new ArrayCollection();
170
        $this->signAttendance = false;
171
    }
172
173
    /**
174
     * @return string
175
     */
176
    public function __toString()
177
    {
178
        return sprintf('Meeting %d', $this->id);
179
    }
180
181
    /**
182
     * @return int
183
     */
184
    public function getId()
185
    {
186
        return $this->id;
187
    }
188
189
    /**
190
     * @return int
191
     */
192
    public function getMeetingId()
193
    {
194
        return $this->meetingId;
195
    }
196
197
    /**
198
     * @param int $meetingId
199
     *
200
     * @return Meeting
201
     */
202
    public function setMeetingId($meetingId)
203
    {
204
        $this->meetingId = $meetingId;
205
206
        return $this;
207
    }
208
209
    /**
210
     * @return User
211
     */
212
    public function getUser()
213
    {
214
        return $this->user;
215
    }
216
217
    /**
218
     * @return Course
219
     */
220
    public function getCourse()
221
    {
222
        return $this->course;
223
    }
224
225
    /**
226
     * @return Session
227
     */
228
    public function getSession()
229
    {
230
        return $this->session;
231
    }
232
233
    /**
234
     * @return Registrant[]|ArrayCollection
235
     */
236
    public function getRegistrants()
237
    {
238
        return $this->registrants;
239
    }
240
241
    /**
242
     * @return Recording[]|ArrayCollection
243
     */
244
    public function getRecordings()
245
    {
246
        return $this->recordings;
247
    }
248
249
    /**
250
     * @return MeetingActivity[]|ArrayCollection
251
     */
252
    public function getActivities()
253
    {
254
        return $this->activities;
255
    }
256
257
    public function addActivity(MeetingActivity $activity)
258
    {
259
        $activity->setMeeting($this);
260
        $this->activities[] = $activity;
261
    }
262
263
    /**
264
     * @param MeetingActivity[]|ArrayCollection $activities
265
     *
266
     * @return Meeting
267
     */
268
    public function setActivities($activities)
269
    {
270
        $this->activities = $activities;
271
272
        return $this;
273
    }
274
275
    /**
276
     * @ORM\PostLoad
277
     *
278
     * @throws Exception
279
     */
280
    public function postLoad()
281
    {
282
        if (null !== $this->meetingListItemJson) {
283
            $this->meetingListItem = MeetingListItem::fromJson($this->meetingListItemJson);
284
        }
285
        if (null !== $this->meetingInfoGetJson) {
286
            $this->meetingInfoGet = MeetingInfoGet::fromJson($this->meetingInfoGetJson);
287
        }
288
        $this->initializeDisplayableProperties();
289
    }
290
291
    /**
292
     * @ORM\PostUpdate
293
     *
294
     * @throws Exception
295
     */
296
    public function postUpdate()
297
    {
298
        $this->initializeDisplayableProperties();
299
    }
300
301
    /**
302
     * @ORM\PreFlush
303
     */
304
    public function preFlush()
305
    {
306
        if (null !== $this->meetingListItem) {
307
            $this->meetingListItemJson = json_encode($this->meetingListItem);
308
        }
309
        if (null !== $this->meetingInfoGet) {
310
            $this->meetingInfoGetJson = json_encode($this->meetingInfoGet);
311
        }
312
    }
313
314
    /**
315
     * @return MeetingListItem
316
     */
317
    public function getMeetingListItem()
318
    {
319
        return $this->meetingListItem;
320
    }
321
322
    /**
323
     * @return MeetingInfoGet
324
     */
325
    public function getMeetingInfoGet()
326
    {
327
        return $this->meetingInfoGet;
328
    }
329
330
    /**
331
     * @param User $user
332
     *
333
     * @return $this
334
     */
335
    public function setUser($user)
336
    {
337
        $this->user = $user;
338
339
        return $this;
340
    }
341
342
    /**
343
     * @param Course $course
344
     *
345
     * @return $this
346
     */
347
    public function setCourse($course)
348
    {
349
        $this->course = $course;
350
351
        return $this;
352
    }
353
354
    /**
355
     * @param Session $session
356
     *
357
     * @return $this
358
     */
359
    public function setSession($session)
360
    {
361
        $this->session = $session;
362
363
        return $this;
364
    }
365
366
    /**
367
     * @return CGroupInfo
368
     */
369
    public function getGroup()
370
    {
371
        return $this->group;
372
    }
373
374
    /**
375
     * @param CGroupInfo $group
376
     *
377
     * @return Meeting
378
     */
379
    public function setGroup($group)
380
    {
381
        $this->group = $group;
382
383
        return $this;
384
    }
385
386
    /**
387
     * @param MeetingListItem $meetingListItem
388
     *
389
     * @throws Exception
390
     *
391
     * @return Meeting
392
     */
393
    public function setMeetingListItem($meetingListItem)
394
    {
395
        if (null === $this->meetingId) {
396
            $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...
397
        } elseif ($this->meetingId != $meetingListItem->id) {
398
            throw new Exception('the Meeting identifier differs from the MeetingListItem identifier');
399
        }
400
        $this->meetingListItem = $meetingListItem;
401
402
        return $this;
403
    }
404
405
    /**
406
     * @param MeetingInfoGet|BaseMeetingTrait $meetingInfoGet
407
     *
408
     * @throws Exception
409
     *
410
     * @return Meeting
411
     */
412
    public function setMeetingInfoGet($meetingInfoGet)
413
    {
414
        if (null === $this->meetingId) {
415
            $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...
416
        } elseif ($this->meetingId != $meetingInfoGet->id) {
417
            throw new Exception('the Meeting identifier differs from the MeetingInfoGet identifier');
418
        }
419
        $this->meetingInfoGet = $meetingInfoGet;
420
        $this->initializeDisplayableProperties();
421
422
        return $this;
423
    }
424
425
    /**
426
     * @return bool
427
     */
428
    public function isCourseMeeting()
429
    {
430
        return null !== $this->course;
431
    }
432
433
    /**
434
     * @return bool
435
     */
436
    public function isCourseGroupMeeting()
437
    {
438
        return null !== $this->course && null !== $this->group;
439
    }
440
441
    /**
442
     * @return bool
443
     */
444
    public function isUserMeeting()
445
    {
446
        return null !== $this->user && null === $this->course;
447
    }
448
449
    /**
450
     * @return bool
451
     */
452
    public function isGlobalMeeting()
453
    {
454
        return null === $this->user && null === $this->course;
455
    }
456
457
    public function setStatus($status)
458
    {
459
        $this->meetingInfoGet->status = $status;
460
    }
461
462
    /**
463
     * Builds the list of users that can register into this meeting.
464
     * Zoom requires an email address, therefore users without an email address are excluded from the list.
465
     *
466
     * @return User[] the list of users
467
     */
468
    public function getRegistrableUsers()
469
    {
470
        $users = [];
471
        if (!$this->isCourseMeeting()) {
472
            $criteria = ['active' => true];
473
            $users = Database::getManager()->getRepository('ChamiloUserBundle:User')->findBy($criteria);
474
        } elseif (null === $this->session) {
475
            if (null !== $this->course) {
476
                /** @var CourseRelUser $courseRelUser */
477
                foreach ($this->course->getUsers() as $courseRelUser) {
478
                    $users[] = $courseRelUser->getUser();
479
                }
480
            }
481
        } else {
482
            if (null !== $this->course) {
483
                $subscriptions = $this->session->getUserCourseSubscriptionsByStatus($this->course, Session::STUDENT);
484
                if ($subscriptions) {
485
                    /** @var SessionRelCourseRelUser $sessionCourseUser */
486
                    foreach ($subscriptions as $sessionCourseUser) {
487
                        $users[] = $sessionCourseUser->getUser();
488
                    }
489
                }
490
            }
491
        }
492
493
        $activeUsersWithEmail = [];
494
        foreach ($users as $user) {
495
            if ($user->isActive() && !empty($user->getEmail())) {
496
                $activeUsersWithEmail[] = $user;
497
            }
498
        }
499
500
        return $activeUsersWithEmail;
501
    }
502
503
    /**
504
     * @return bool
505
     */
506
    public function requiresDateAndDuration()
507
    {
508
        return MeetingInfoGet::TYPE_SCHEDULED === $this->meetingInfoGet->type
509
            || MeetingInfoGet::TYPE_RECURRING_WITH_FIXED_TIME === $this->meetingInfoGet->type;
510
    }
511
512
    public function requiresRegistration(): bool
513
    {
514
        return true; //MeetingSettings::APPROVAL_TYPE_AUTOMATICALLY_APPROVE === $this->meetingInfoGet->settings->approval_type;
515
        /*return
516
            MeetingSettings::APPROVAL_TYPE_NO_REGISTRATION_REQUIRED != $this->meetingInfoGet->settings->approval_type;*/
517
    }
518
519
    /**
520
     * @return bool
521
     */
522
    public function hasCloudAutoRecordingEnabled()
523
    {
524
        return \ZoomPlugin::RECORDING_TYPE_NONE !== $this->meetingInfoGet->settings->auto_recording;
525
    }
526
527
    public function getRegistrantByUser(User $user): ?Registrant
528
    {
529
        $criteria = Criteria::create()
530
            ->where(
531
                Criteria::expr()->eq('user', $user)
532
            )
533
        ;
534
535
        return $this->registrants->matching($criteria)->first() ?? null;
536
    }
537
538
    /**
539
     * Generates a short presentation of the meeting for the future participant.
540
     * To be displayed above the "Enter meeting" link.
541
     *
542
     * @return string
543
     */
544
    public function getIntroduction()
545
    {
546
        $introduction = sprintf('<h1>%s</h1>', $this->getTopic()).PHP_EOL;
547
        if (!$this->isGlobalMeeting()) {
548
            if (!empty($this->formattedStartTime)) {
549
                $introduction .= $this->formattedStartTime;
550
                if (!empty($this->formattedDuration)) {
551
                    $introduction .= ' ('.$this->formattedDuration.')';
552
                }
553
                $introduction .= PHP_EOL;
554
            }
555
        }
556
        if ($this->user) {
557
            $introduction .= sprintf('<p>%s</p>', $this->user->getFullname()).PHP_EOL;
558
        } elseif ($this->isCourseMeeting()) {
559
            if (null === $this->session) {
560
                $introduction .= sprintf('<p class="main">%s</p>', $this->course).PHP_EOL;
561
            } else {
562
                $introduction .= sprintf('<p class="main">%s (%s)</p>', $this->course, $this->session).PHP_EOL;
563
            }
564
        }
565
566
        if (!empty($this->getAgenda())) {
567
            $introduction .= sprintf('<p>%s</p>', $this->getAgenda()).PHP_EOL;
568
        }
569
570
        return $introduction;
571
    }
572
573
    public function isSignAttendance(): bool
574
    {
575
        return $this->signAttendance;
576
    }
577
578
    public function setSignAttendance(bool $signAttendance): Meeting
579
    {
580
        $this->signAttendance = $signAttendance;
581
582
        return $this;
583
    }
584
585
    public function getAccountEmail(): ?string
586
    {
587
        return $this->accountEmail;
588
    }
589
590
    public function setAccountEmail(?string $accountEmail): self
591
    {
592
        $this->accountEmail = $accountEmail;
593
594
        return $this;
595
    }
596
597
    public function getReasonToSignAttendance(): ?string
598
    {
599
        return $this->reasonToSignAttendance;
600
    }
601
602
    public function setReasonToSignAttendance(string $reasonToSignAttendance): Meeting
603
    {
604
        $this->reasonToSignAttendance = $reasonToSignAttendance;
605
606
        return $this;
607
    }
608
609
    public function getTopic(): string
610
    {
611
        return $this->meetingInfoGet->topic;
612
    }
613
614
    public function getAgenda(): ?string
615
    {
616
        return $this->meetingInfoGet->agenda;
617
    }
618
619
    /**
620
     * @throws Exception on unexpected start_time or duration
621
     */
622
    protected function initializeDisplayableProperties()
623
    {
624
        $zoomPlugin = new \ZoomPlugin();
625
626
        $typeList = [
627
            API\Meeting::TYPE_INSTANT => $zoomPlugin->get_lang('InstantMeeting'),
628
            API\Meeting::TYPE_SCHEDULED => $zoomPlugin->get_lang('ScheduledMeeting'),
629
            API\Meeting::TYPE_RECURRING_WITH_NO_FIXED_TIME => $zoomPlugin->get_lang('RecurringWithNoFixedTime'),
630
            API\Meeting::TYPE_RECURRING_WITH_FIXED_TIME => $zoomPlugin->get_lang('RecurringWithFixedTime'),
631
        ];
632
        $this->typeName = $typeList[$this->meetingInfoGet->type];
633
634
        if (property_exists($this, 'status')) {
635
            $statusList = [
636
                'waiting' => $zoomPlugin->get_lang('Waiting'),
637
                'started' => $zoomPlugin->get_lang('Started'),
638
                'finished' => $zoomPlugin->get_lang('Finished'),
639
            ];
640
            $this->statusName = $statusList[$this->meetingInfoGet->status];
641
        }
642
        $this->startDateTime = null;
643
        $this->formattedStartTime = '';
644
        $this->durationInterval = null;
645
        $this->formattedDuration = '';
646
        if (!empty($this->meetingInfoGet->start_time)) {
647
            $this->startDateTime = new DateTime($this->meetingInfoGet->start_time);
648
            $this->startDateTime->setTimezone(new DateTimeZone(api_get_timezone()));
649
            $this->formattedStartTime = $this->startDateTime->format('Y-m-d H:i');
650
        }
651
652
        if (!empty($this->meetingInfoGet->duration)) {
653
            $now = new DateTime();
654
            $later = new DateTime();
655
            $later->add(new DateInterval('PT'.$this->meetingInfoGet->duration.'M'));
656
            $this->durationInterval = $now->diff($later);
657
            $this->formattedDuration = $this->durationInterval->format($zoomPlugin->get_lang('DurationFormat'));
658
        }
659
    }
660
}
661