Passed
Pull Request — 1.11.x (#4151)
by Angel Fernando Quiroz
09:24
created

Meeting::postUpdate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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