Passed
Push — 1.11.x ( 107d15...5ca88d )
by Julito
14:45 queued 13s
created

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

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
604
            $this->formattedDuration = $this->durationInterval->format($zoomPlugin->get_lang('DurationFormat'));
605
        }
606
    }
607
}
608