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

Meeting::addActivity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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