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

bbb::getCountMeetings()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 61
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 34
c 0
b 0
f 0
dl 0
loc 61
rs 8.4426
cc 7
nc 10
nop 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * Class bbb
7
 * This script initiates a video conference session, calling the BigBlueButton
8
 * API BigBlueButton-Chamilo connector class
9
 */
10
class bbb
11
{
12
    public $url;
13
    public $salt;
14
    public $api;
15
    public $userCompleteName = '';
16
    public $protocol = 'http://';
17
    public $debug = false;
18
    public $logoutUrl = '';
19
    public $pluginEnabled = false;
20
    public $enableGlobalConference = false;
21
    public $enableGlobalConferencePerUser = false;
22
    public $isGlobalConference = false;
23
    public $groupSupport = false;
24
    public $userSupport = false;
25
    public $accessUrl = 1;
26
    public $userId = 0;
27
    public $plugin;
28
    private $courseCode;
29
    private $courseId;
30
    private $sessionId;
31
    private $groupId;
32
    private $maxUsersLimit;
33
34
    /**
35
     * Constructor (generates a connection to the API and the Chamilo settings
36
     * required for the connection to the video conference server)
37
     *
38
     * @param string $host
39
     * @param string $salt
40
     * @param bool   $isGlobalConference
41
     * @param int    $isGlobalPerUser
42
     */
43
    public function __construct(
44
        $host = '',
45
        $salt = '',
46
        $isGlobalConference = false,
47
        $isGlobalPerUser = 0
48
    ) {
49
        $this->courseCode = api_get_course_id();
50
        $this->courseId = api_get_course_int_id();
51
        $this->sessionId = api_get_session_id();
52
        $this->groupId = api_get_group_id();
53
54
        // Initialize video server settings from global settings
55
        $this->plugin = BBBPlugin::create();
56
        $bbbPluginEnabled = $this->plugin->get('tool_enable');
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
        /** @scrutinizer ignore-call */ 
57
        $bbbPluginEnabled = $this->plugin->get('tool_enable');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
57
58
        $bbb_host = !empty($host) ? $host : $this->plugin->get('host');
59
        $bbb_salt = !empty($salt) ? $salt : $this->plugin->get('salt');
60
61
        $this->table = Database::get_main_table('plugin_bbb_meeting');
62
        $this->enableGlobalConference = $this->plugin->get('enable_global_conference') === 'true';
63
        $this->isGlobalConference = (bool) $isGlobalConference;
64
65
        $columns = Database::listTableColumns($this->table);
66
        $this->groupSupport = isset($columns['group_id']) ? true : false;
67
        $this->userSupport = isset($columns['user_id']) ? true : false;
68
        $this->accessUrl = api_get_current_access_url_id();
69
70
        $this->enableGlobalConferencePerUser = false;
71
        if ($this->userSupport && !empty($isGlobalPerUser)) {
72
            $this->enableGlobalConferencePerUser = $this->plugin->get('enable_global_conference_per_user') === 'true';
73
            $this->userId = $isGlobalPerUser;
74
        }
75
76
        if ($this->groupSupport) {
77
            // Plugin check
78
            $this->groupSupport = $this->plugin->get('enable_conference_in_course_groups') === 'true' ? true : false;
79
            if ($this->groupSupport) {
80
                // Platform check
81
                $bbbSetting = api_get_setting('bbb_enable_conference_in_course_groups');
82
                $bbbSetting = isset($bbbSetting['bbb']) ? $bbbSetting['bbb'] === 'true' : false;
83
84
                if ($bbbSetting) {
85
                    // Course check
86
                    $courseInfo = api_get_course_info();
87
                    if ($courseInfo) {
88
                        $this->groupSupport = api_get_course_plugin_setting(
89
                                'bbb',
90
                                'bbb_enable_conference_in_groups',
91
                                $courseInfo
92
                            ) === '1';
93
                    }
94
                }
95
            }
96
        }
97
        $this->maxUsersLimit = $this->plugin->get('max_users_limit');
98
99
        if ($bbbPluginEnabled === 'true') {
100
            $userInfo = api_get_user_info();
101
            if (empty($userInfo) && !empty($isGlobalPerUser)) {
102
                // If we are following a link to a global "per user" conference
103
                // then generate a random guest name to join the conference
104
                // because there is no part of the process where we give a name
105
                //$this->userCompleteName = 'Guest'.rand(1000, 9999);
106
            } else {
107
                $this->userCompleteName = $userInfo['complete_name'];
108
            }
109
110
            if (api_is_anonymous()) {
111
                $this->userCompleteName = get_lang('Guest').'_'.rand(1000, 9999);
112
            }
113
114
            $this->salt = $bbb_salt;
115
            if (!empty($bbb_host)) {
116
                if (substr($bbb_host, -1, 1) !== '/') {
117
                    $bbb_host .= '/';
118
                }
119
                $this->url = $bbb_host;
120
                if (!preg_match('#/bigbluebutton/$#', $bbb_host)) {
121
                    $this->url = $bbb_host.'bigbluebutton/';
122
                }
123
            }
124
            $info = parse_url($bbb_host);
125
126
            if (isset($info['scheme'])) {
127
                $this->protocol = $info['scheme'].'://';
128
                $this->url = str_replace($this->protocol, '', $this->url);
129
                $urlWithProtocol = $bbb_host;
130
            } else {
131
                // We assume it's an http, if user wants to use https, the host *must* include the protocol.
132
                $this->protocol = 'http://';
133
                $urlWithProtocol = $this->protocol.$bbb_host;
134
            }
135
136
            // Setting BBB api
137
            define('CONFIG_SECURITY_SALT', $this->salt);
138
            define('CONFIG_SERVER_URL_WITH_PROTOCOL', $urlWithProtocol);
139
            define('CONFIG_SERVER_BASE_URL', $this->url);
140
            define('CONFIG_SERVER_PROTOCOL', $this->protocol);
141
142
            $this->api = new BigBlueButtonBN();
143
            $this->pluginEnabled = true;
144
            $this->logoutUrl = $this->getListingUrl();
145
        }
146
    }
147
148
    /**
149
     * @param int $courseId  Optional. Course ID.
150
     * @param int $sessionId Optional. Session ID.
151
     * @param int $groupId   Optional. Group ID.
152
     *
153
     * @return string
154
     */
155
    public function getListingUrl($courseId = 0, $sessionId = 0, $groupId = 0)
156
    {
157
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'
158
            .$this->getUrlParams($courseId, $sessionId, $groupId);
159
    }
160
161
    /**
162
     * @param int $courseId  Optional. Course ID.
163
     * @param int $sessionId Optional. Session ID.
164
     * @param int $groupId   Optional. Group ID.
165
     *
166
     * @return string
167
     */
168
    public function getUrlParams($courseId = 0, $sessionId = 0, $groupId = 0)
169
    {
170
        if (empty($this->courseCode) && !$courseId) {
171
            if ($this->isGlobalConferencePerUserEnabled()) {
172
                return 'global=1&user_id='.$this->userId;
173
            }
174
175
            if ($this->isGlobalConference()) {
176
                return 'global=1';
177
            }
178
179
            return '';
180
        }
181
182
        $courseCode = $this->courseCode;
183
        if (!empty($courseId)) {
184
            $course = api_get_course_info_by_id($courseId);
185
            if ($course) {
186
                $courseCode = $course['code'];
187
            }
188
        }
189
190
        return http_build_query(
191
            [
192
                'cidReq' => $courseCode,
193
                'id_session' => $sessionId ?: $this->sessionId,
194
                'gidReq' => $groupId ?: $this->groupId,
195
            ]
196
        );
197
    }
198
199
    /**
200
     * @return bool
201
     */
202
    public function isGlobalConferencePerUserEnabled()
203
    {
204
        return $this->enableGlobalConferencePerUser;
205
    }
206
207
    /**
208
     * @return bool
209
     */
210
    public function isGlobalConference()
211
    {
212
        if ($this->isGlobalConferenceEnabled() === false) {
213
            return false;
214
        }
215
216
        return (bool) $this->isGlobalConference;
217
    }
218
219
    /**
220
     * @return bool
221
     */
222
    public function isGlobalConferenceEnabled()
223
    {
224
        return $this->enableGlobalConference;
225
    }
226
227
    /**
228
     * @param array $userInfo
229
     *
230
     * @return bool
231
     */
232
    public static function showGlobalConferenceLink($userInfo)
233
    {
234
        if (empty($userInfo)) {
235
            return false;
236
        }
237
        $setting = api_get_plugin_setting('bbb', 'enable_global_conference');
238
        $settingLink = api_get_plugin_setting('bbb', 'enable_global_conference_link');
239
        if ($setting === 'true' && $settingLink === 'true') {
240
            //$content = Display::url(get_lang('LaunchVideoConferenceRoom'), $url);
241
            $allowedRoles = api_get_plugin_setting(
242
                'bbb',
243
                'global_conference_allow_roles'
244
            );
245
246
            if (api_is_platform_admin()) {
247
                $userInfo['status'] = PLATFORM_ADMIN;
248
            }
249
250
            $showGlobalLink = true;
251
            if (!empty($allowedRoles)) {
252
                if (!in_array($userInfo['status'], $allowedRoles)) {
253
                    $showGlobalLink = false;
254
                }
255
            }
256
257
            return $showGlobalLink;
258
        }
259
    }
260
261
    /**
262
     * Gets the global limit of users in a video-conference room.
263
     * This value can be overridden by course-specific values
264
     * @return  int Maximum number of users set globally
265
     */
266
    public function getMaxUsersLimit()
267
    {
268
        $limit = $this->maxUsersLimit;
269
        if ($limit <= 0) {
270
            $limit = 0;
271
        }
272
        $courseLimit = 0;
273
        $sessionLimit = 0;
274
        // Check the extra fields for this course and session
275
        // Session limit takes priority over course limit
276
        // Course limit takes priority over global limit
277
        if (!empty($this->courseId)) {
278
            $extraField = new ExtraField('course');
279
            $fieldId = $extraField->get_all(
280
                array('variable = ?' => 'plugin_bbb_course_users_limit')
281
            );
282
            $extraValue = new ExtraFieldValue('course');
283
            $value = $extraValue->get_values_by_handler_and_field_id($this->courseId, $fieldId[0]['id']);
284
            if (!empty($value['value'])) {
285
                $courseLimit = (int) $value['value'];
286
            }
287
        }
288
        if (!empty($this->sessionId)) {
289
            $extraField = new ExtraField('session');
290
            $fieldId = $extraField->get_all(
291
                array('variable = ?' => 'plugin_bbb_session_users_limit')
292
            );
293
            $extraValue = new ExtraFieldValue('session');
294
            $value = $extraValue->get_values_by_handler_and_field_id($this->sessionId, $fieldId[0]['id']);
295
            if (!empty($value['value'])) {
296
                $sessionLimit = (int) $value['value'];
297
            }
298
        }
299
300
        if (!empty($sessionLimit)) {
301
            return $sessionLimit;
302
        } elseif (!empty($courseLimit)) {
303
            return $courseLimit;
304
        }
305
306
        return (int) $limit;
307
    }
308
309
    /**
310
     * Sets the global limit of users in a video-conference room.
311
     *
312
     * @param int Maximum number of users (globally)
313
     */
314
    public function setMaxUsersLimit($max)
315
    {
316
        if ($max < 0) {
317
            $max = 0;
318
        }
319
        $this->maxUsersLimit = (int) $max;
320
    }
321
322
    /**
323
     * See this file in you BBB to set up default values
324
     *
325
     * @param array $params Array of parameters that will be completed if not containing all expected variables
326
     *
327
     * /var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties
328
     *
329
     * More record information:
330
     * http://code.google.com/p/bigbluebutton/wiki/RecordPlaybackSpecification
331
     *
332
     * Default maximum number of users a meeting can have.
333
     * Doesn't get enforced yet but is the default value when the create
334
     * API doesn't pass a value.
335
     * defaultMaxUsers=20
336
     *
337
     * Default duration of the meeting in minutes.
338
     * Current default is 0 (meeting doesn't end).
339
     * defaultMeetingDuration=0
340
     *
341
     * Remove the meeting from memory when the end API is called.
342
     * This allows 3rd-party apps to recycle the meeting right-away
343
     * instead of waiting for the meeting to expire (see below).
344
     * removeMeetingWhenEnded=false
345
     *
346
     * The number of minutes before the system removes the meeting from memory.
347
     * defaultMeetingExpireDuration=1
348
     *
349
     * The number of minutes the system waits when a meeting is created and when
350
     * a user joins. If after this period, a user hasn't joined, the meeting is
351
     * removed from memory.
352
     * defaultMeetingCreateJoinDuration=5
353
     *
354
     * @return mixed
355
     */
356
    public function createMeeting($params)
357
    {
358
        $params['c_id'] = api_get_course_int_id();
359
        $params['session_id'] = api_get_session_id();
360
361
        if ($this->hasGroupSupport()) {
362
            $params['group_id'] = api_get_group_id();
363
        }
364
365
        if ($this->isGlobalConferencePerUserEnabled() && !empty($this->userId)) {
366
            $params['user_id'] = (int) $this->userId;
367
        }
368
369
        $params['attendee_pw'] = isset($params['attendee_pw']) ? $params['attendee_pw'] : $this->getUserMeetingPassword();
370
        $attendeePassword = $params['attendee_pw'];
371
        $params['moderator_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $this->getModMeetingPassword();
372
        $moderatorPassword = $params['moderator_pw'];
373
374
        $params['record'] = api_get_course_plugin_setting('bbb', 'big_blue_button_record_and_store') == 1;
375
        $max = api_get_course_plugin_setting('bbb', 'max_users_limit');
376
        $max = isset($max) ? $max : -1;
377
378
        $params['status'] = 1;
379
        // Generate a pseudo-global-unique-id to avoid clash of conferences on
380
        // the same BBB server with several Chamilo portals
381
        $params['remote_id'] = uniqid(true, true);
382
        // Each simultaneous conference room needs to have a different
383
        // voice_bridge composed of a 5 digits number, so generating a random one
384
        $params['voice_bridge'] = rand(10000, 99999);
385
        $params['created_at'] = api_get_utc_datetime();
386
        $params['access_url'] = $this->accessUrl;
387
388
        $id = Database::insert($this->table, $params);
389
390
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
391
            Event::addEvent(
0 ignored issues
show
Bug introduced by
The method addEvent() does not exist on Event. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

391
            Event::/** @scrutinizer ignore-call */ 
392
                   addEvent(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
392
                'bbb_create_meeting',
393
                'meeting_id',
394
                (int) $id,
395
                null,
396
                api_get_user_id(),
397
                api_get_course_int_id(),
398
                api_get_session_id()
399
            );
400
401
            $meetingName = isset($params['meeting_name']) ? $params['meeting_name'] : $this->getCurrentVideoConferenceName();
402
            $welcomeMessage = isset($params['welcome_msg']) ? $params['welcome_msg'] : null;
403
            $record = isset($params['record']) && $params['record'] ? 'true' : 'false';
404
            //$duration = isset($params['duration']) ? intval($params['duration']) : 0;
405
            // This setting currently limits the maximum conference duration,
406
            // to avoid lingering sessions on the video-conference server #6261
407
            $duration = 300;
408
            $meetingDuration = (int) $this->plugin->get('meeting_duration');
409
            if (!empty($meetingDuration)) {
410
                $duration = $meetingDuration;
411
            }
412
            $bbbParams = array(
413
                'meetingId' => $params['remote_id'], // REQUIRED
414
                'meetingName' => $meetingName, // REQUIRED
415
                'attendeePw' => $attendeePassword, // Match this value in getJoinMeetingURL() to join as attendee.
416
                'moderatorPw' => $moderatorPassword, // Match this value in getJoinMeetingURL() to join as moderator.
417
                'welcomeMsg' => $welcomeMessage, // ''= use default. Change to customize.
418
                'dialNumber' => '', // The main number to call into. Optional.
419
                'voiceBridge' => $params['voice_bridge'], // PIN to join voice. Required.
420
                'webVoice' => '', // Alphanumeric to join voice. Optional.
421
                'logoutUrl' => $this->logoutUrl.'&action=logout&remote_id='.$params['remote_id'],
422
                'maxParticipants' => $max, // Optional. -1 = unlimitted. Not supported in BBB. [number]
423
                'record' => $record, // New. 'true' will tell BBB to record the meeting.
424
                'duration' => $duration, // Default = 0 which means no set duration in minutes. [number]
425
                //'meta_category' => '',  // Use to pass additional info to BBB server. See API docs.
426
            );
427
428
            $status = false;
429
            $meeting = null;
430
            while ($status === false) {
431
                $result = $this->api->createMeetingWithXmlResponseArray($bbbParams);
432
                if (isset($result) && strval($result['returncode']) == 'SUCCESS') {
433
                    if ($this->plugin->get('allow_regenerate_recording') === 'true') {
434
                        $internalId = Database::escape_string($result['internalMeetingID']);
435
                        $sql = "UPDATE $this->table SET internal_meeting_id = '".$internalId."'
436
                                WHERE id = $id";
437
                        Database::query($sql);
438
                    }
439
                    $meeting = $this->joinMeeting($meetingName, true);
440
441
                    return $meeting;
442
                }
443
            }
444
        }
445
446
        return false;
447
    }
448
449
    /**
450
     * @return bool
451
     */
452
    public function hasGroupSupport()
453
    {
454
        return $this->groupSupport;
455
    }
456
457
    /**
458
     * Gets the password for a specific meeting for the current user
459
     *
460
     * @param string $courseCode
461
     *
462
     * @return string A moderator password if user is teacher, or the course code otherwise
463
     *
464
     */
465
    public function getUserMeetingPassword($courseCode = null)
466
    {
467
        if ($this->isGlobalConferencePerUserEnabled()) {
468
            return 'url_'.$this->userId.'_'.api_get_current_access_url_id();
469
        }
470
471
        if ($this->isGlobalConference()) {
472
            return 'url_'.api_get_current_access_url_id();
473
        }
474
        $courseCode = empty($courseCode) ? api_get_course_id() : $courseCode;
475
476
        return $courseCode;
477
    }
478
479
    /**
480
     * Generated a moderator password for the meeting.
481
     *
482
     * @param string $courseCode
483
     *
484
     * @return string A password for the moderation of the videoconference
485
     */
486
    public function getModMeetingPassword($courseCode = null)
487
    {
488
        if ($this->isGlobalConferencePerUserEnabled()) {
489
            return 'url_'.$this->userId.'_'.api_get_current_access_url_id().'_mod';
490
        }
491
492
        if ($this->isGlobalConference()) {
493
            return 'url_'.api_get_current_access_url_id().'_mod';
494
        }
495
496
        $courseCode = empty($courseCode) ? api_get_course_id() : $courseCode;
497
498
        return $courseCode.'mod';
499
    }
500
501
    public function getCurrentVideoConferenceName(string $defaultName = null): string
502
    {
503
        $nameFilter = function ($name) {
504
            return URLify::filter(
505
                $name,
506
                64,
507
                '',
508
                true,
509
                true,
510
                true,
511
                false
512
            );
513
        };
514
515
        if (!empty($defaultName)) {
516
            $name = $nameFilter($defaultName);
517
518
            if (!empty($name)) {
519
                return $name;
520
            }
521
        }
522
523
        $urlId = api_get_current_access_url_id();
524
525
        if ($this->isGlobalConferencePerUserEnabled()) {
526
            return $nameFilter("url_{$this->userId}_$urlId");
527
        }
528
529
        if ($this->isGlobalConference()) {
530
            return $nameFilter("url_$urlId");
531
        }
532
533
        $course = api_get_course_entity();
534
        $session = api_get_session_entity();
535
        $group = api_get_group_entity();
536
537
        if ($this->hasGroupSupport()) {
538
            $name = implode(
539
                '-',
540
                [
541
                    $course->getCode(),
542
                    $session ? $session->getName() : '',
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
543
                    $group ? $group->getName() : '',
544
                ]
545
            );
546
547
            return $nameFilter($name);
548
        }
549
550
        $name = implode(
551
            '-',
552
            [
553
                $course->getCode(),
554
                $session ? $session->getName() : '',
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
555
            ]
556
        );
557
558
        return $nameFilter($name);
559
    }
560
561
    /**
562
     * Returns a meeting "join" URL
563
     *
564
     * @param string The name of the meeting (usually the course code)
565
     *
566
     * @return mixed The URL to join the meeting, or false on error
567
     * @todo implement moderator pass
568
     * @assert ('') === false
569
     * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
570
     */
571
    public function joinMeeting($meetingName)
572
    {
573
        if ($this->debug) {
574
            error_log("joinMeeting: $meetingName");
575
        }
576
577
        if (empty($meetingName)) {
578
            return false;
579
        }
580
581
        $manager = $this->isConferenceManager();
582
        if ($manager) {
583
            $pass = $this->getModMeetingPassword();
584
        } else {
585
            $pass = $this->getUserMeetingPassword();
586
        }
587
588
        $meetingData = Database::select(
589
            '*',
590
            $this->table,
591
            array(
592
                'where' => array(
593
                    'meeting_name = ? AND status = 1 AND access_url = ?' => array(
594
                        $meetingName,
595
                        $this->accessUrl,
596
                    ),
597
                ),
598
            ),
599
            'first'
600
        );
601
602
        if (empty($meetingData) || !is_array($meetingData)) {
603
            if ($this->debug) {
604
                error_log("meeting does not exist: $meetingName");
605
            }
606
607
            return false;
608
        }
609
610
        $params = array(
611
            'meetingId' => $meetingData['remote_id'],
612
            //  -- REQUIRED - The unique id for the meeting
613
            'password' => $this->getModMeetingPassword()
614
            //  -- REQUIRED - The moderator password for the meeting
615
        );
616
617
        $meetingInfoExists = false;
618
        $meetingIsRunningInfo = $this->getMeetingInfo($params);
619
        if ($this->debug) {
620
            error_log('Searching meeting with params:');
621
            error_log(print_r($params, 1));
622
            error_log('Result:');
623
            error_log(print_r($meetingIsRunningInfo, 1));
624
        }
625
626
        if ($meetingIsRunningInfo === false) {
627
            // checking with the remote_id didn't work, so just in case and
628
            // to provide backwards support, check with the id
629
            $params = array(
630
                'meetingId' => $meetingData['id'],
631
                //  -- REQUIRED - The unique id for the meeting
632
                'password' => $this->getModMeetingPassword()
633
                //  -- REQUIRED - The moderator password for the meeting
634
            );
635
            $meetingIsRunningInfo = $this->getMeetingInfo($params);
636
            if ($this->debug) {
637
                error_log('Searching meetingId with params:');
638
                error_log(print_r($params, 1));
639
                error_log('Result:');
640
                error_log(print_r($meetingIsRunningInfo, 1));
641
            }
642
        }
643
644
        if (strval($meetingIsRunningInfo['returncode']) === 'SUCCESS' &&
645
            isset($meetingIsRunningInfo['meetingName']) &&
646
            !empty($meetingIsRunningInfo['meetingName'])
647
        ) {
648
            $meetingInfoExists = true;
649
        }
650
651
        if ($this->debug) {
652
            error_log(
653
                "meeting is running: ".intval($meetingInfoExists)
654
            );
655
        }
656
657
        $url = false;
658
        if ($meetingInfoExists) {
659
            $joinParams = [
660
                'meetingId' => $meetingData['remote_id'],
661
                //	-- REQUIRED - A unique id for the meeting
662
                'username' => $this->userCompleteName,
663
                //-- REQUIRED - The name that will display for the user in the meeting
664
                'password' => $pass,
665
                //-- REQUIRED - The attendee or moderator password, depending on what's passed here
666
                //'createTime' => api_get_utc_datetime(),			//-- OPTIONAL - string. Leave blank ('') unless you set this correctly.
667
                'userID' => api_get_user_id(),
668
                //-- OPTIONAL - string
669
                'webVoiceConf' => '',
670
            ];
671
            $url = $this->api->getJoinMeetingURL($joinParams);
672
            $url = $this->protocol.$url;
673
        }
674
675
        if ($this->debug) {
676
            error_log("return url :".$url);
0 ignored issues
show
Bug introduced by
Are you sure $url of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

676
            error_log("return url :"./** @scrutinizer ignore-type */ $url);
Loading history...
677
        }
678
679
        return $url;
680
    }
681
682
    /**
683
     * Checks whether a user is teacher in the current course
684
     * @return bool True if the user can be considered a teacher in this course, false otherwise
685
     */
686
    public function isConferenceManager()
687
    {
688
        if (api_is_coach() || api_is_platform_admin(false, true)) {
689
            return true;
690
        }
691
692
        if ($this->isGlobalConferencePerUserEnabled()) {
693
            $currentUserId = api_get_user_id();
694
            if ($this->userId === $currentUserId) {
695
                return true;
696
            } else {
697
                return false;
698
            }
699
        }
700
701
        $courseInfo = api_get_course_info();
702
        $groupId = api_get_group_id();
703
        if (!empty($groupId) && !empty($courseInfo)) {
704
            $groupEnabled = api_get_course_plugin_setting('bbb', 'bbb_enable_conference_in_groups') === '1';
705
            if ($groupEnabled) {
706
                $studentCanStartConference = api_get_course_plugin_setting(
707
                        'bbb',
708
                        'big_blue_button_students_start_conference_in_groups'
709
                    ) === '1';
710
711
                if ($studentCanStartConference) {
712
                    $isSubscribed = GroupManager::is_user_in_group(
713
                        api_get_user_id(),
714
                        GroupManager::get_group_properties($groupId)
715
                    );
716
                    if ($isSubscribed) {
717
                        return true;
718
                    }
719
                }
720
            }
721
        }
722
723
        if (!empty($courseInfo)) {
724
            return api_is_course_admin();
725
        }
726
727
        return false;
728
    }
729
730
    /**
731
     * Get information about the given meeting
732
     *
733
     * @param array ...?
734
     *
735
     * @return mixed Array of information on success, false on error
736
     * @assert (array()) === false
737
     */
738
    public function getMeetingInfo($params)
739
    {
740
        try {
741
            $result = $this->api->getMeetingInfoWithXmlResponseArray($params);
742
            if ($result == null) {
743
                if ($this->debug) {
744
                    error_log("Failed to get any response. Maybe we can't contact the BBB server.");
745
                }
746
            }
747
748
            return $result;
749
        } catch (Exception $e) {
750
            if ($this->debug) {
751
                error_log('Caught exception: ', $e->getMessage(), "\n");
752
            }
753
        }
754
755
        return false;
756
    }
757
758
759
    /**
760
     * @param int $meetingId
761
     * @param int $userId
762
     *
763
     * @return array
764
     */
765
    public function getMeetingParticipantInfo($meetingId, $userId)
766
    {
767
        $meetingData = Database::select(
768
            '*',
769
            'plugin_bbb_room',
770
            array('where' => array('meeting_id = ? AND participant_id = ?' => [$meetingId, $userId])),
771
            'first'
772
        );
773
774
        if ($meetingData) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $meetingData of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
775
            return $meetingData;
776
        }
777
778
        return [];
779
    }
780
781
    /**
782
     * Save a participant in a meeting room
783
     *
784
     * @param int $meetingId
785
     * @param int $participantId
786
     *
787
     * @return false|int The last inserted ID. Otherwise return false
788
     */
789
    public function saveParticipant($meetingId, $participantId)
790
    {
791
        $meetingData = Database::select(
792
            '*',
793
            'plugin_bbb_room',
794
            [
795
                'where' => [
796
                    'meeting_id = ? AND participant_id = ? AND close = ?' => [
797
                        $meetingId,
798
                        $participantId,
799
                        BBBPlugin::ROOM_OPEN,
800
                    ],
801
                ],
802
            ]
803
        );
804
805
        foreach ($meetingData as $roomItem) {
806
            $inAt = $roomItem['in_at'];
807
            $outAt = $roomItem['out_at'];
808
            $roomId = $roomItem['id'];
809
            if (!empty($roomId)) {
810
                if ($inAt != $outAt) {
811
                    Database::update(
812
                        'plugin_bbb_room',
813
                        ['close' => BBBPlugin::ROOM_CLOSE],
814
                        ['id = ? ' => $roomId]
815
                    );
816
                } else {
817
                    Database::update(
818
                        'plugin_bbb_room',
819
                        ['out_at' => api_get_utc_datetime(), 'close' => BBBPlugin::ROOM_CLOSE],
820
                        ['id = ? ' => $roomId]
821
                    );
822
                }
823
            }
824
        }
825
826
        $params = [
827
            'meeting_id' => $meetingId,
828
            'participant_id' => $participantId,
829
            'in_at' => api_get_utc_datetime(),
830
            'out_at' => api_get_utc_datetime(),
831
            'close' => BBBPlugin::ROOM_OPEN,
832
        ];
833
834
        return Database::insert(
835
            'plugin_bbb_room',
836
            $params
837
        );
838
    }
839
840
    /**
841
     * Tells whether the given meeting exists and is running
842
     * (using course code as name)
843
     *
844
     * @param string $meetingName Meeting name (usually the course code)
845
     *
846
     * @return bool True if meeting exists, false otherwise
847
     * @assert ('') === false
848
     * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
849
     */
850
    public function meetingExists($meetingName)
851
    {
852
        $meetingData = $this->getMeetingByName($meetingName);
853
854
        return !empty($meetingData);
855
    }
856
857
    /**
858
     * @param string $meetingName
859
     *
860
     * @return array
861
     */
862
    public function getMeetingByName($meetingName)
863
    {
864
        if (empty($meetingName)) {
865
            return [];
866
        }
867
868
        $courseId = api_get_course_int_id();
869
        $sessionId = api_get_session_id();
870
        $conditions = array(
871
            'where' => array(
872
                'c_id = ? AND session_id = ? AND meeting_name = ? AND status = 1 AND access_url = ?' =>
873
                    array($courseId, $sessionId, $meetingName, $this->accessUrl),
874
            ),
875
        );
876
877
        if ($this->hasGroupSupport()) {
878
            $groupId = api_get_group_id();
879
            $conditions = array(
880
                'where' => array(
881
                    'c_id = ? AND session_id = ? AND meeting_name = ? AND group_id = ? AND status = 1 AND access_url = ?' =>
882
                        array(
883
                            $courseId,
884
                            $sessionId,
885
                            $meetingName,
886
                            $groupId,
887
                            $this->accessUrl,
888
                        ),
889
                ),
890
            );
891
        }
892
893
        $meetingData = Database::select(
894
            '*',
895
            $this->table,
896
            $conditions,
897
            'first'
898
        );
899
900
        if ($this->debug) {
901
            error_log('meeting_exists '.print_r($meetingData, 1));
0 ignored issues
show
Bug introduced by
Are you sure print_r($meetingData, 1) of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

901
            error_log('meeting_exists './** @scrutinizer ignore-type */ print_r($meetingData, 1));
Loading history...
902
        }
903
904
        return $meetingData;
905
    }
906
907
    /**
908
     * Gets a list from the database of all meetings attached to a course with the given status
909
     * @param int $courseId
910
     * @param int $sessionId
911
     * @param int $status 0 for closed meetings, 1 for open meetings
912
     *
913
     * @return array
914
     */
915
    public function getAllMeetingsInCourse($courseId, $sessionId, $status)
916
    {
917
        $conditions = array(
918
            'where' => array(
919
                'status = ? AND c_id = ? AND session_id = ? ' => array(
920
                    $status,
921
                    $courseId,
922
                    $sessionId,
923
                ),
924
            ),
925
        );
926
927
        return Database::select(
928
            '*',
929
            $this->table,
930
            $conditions
931
        );
932
    }
933
934
    /**
935
     * Gets all the course meetings saved in the plugin_bbb_meeting table and
936
     * generate actionable links (join/close/delete/etc)
937
     *
938
     * @param int   $courseId
939
     * @param int   $sessionId
940
     * @param int   $groupId
941
     * @param bool  $isAdminReport Optional. Set to true then the report is for admins
942
     * @param array $dateRange     Optional
943
     * @param int   $start         Optional
944
     * @param int   $limit         Optional
945
     *
946
     * @return array Array of current open meeting rooms
947
     * @throws Exception
948
     */
949
    public function getMeetings(
950
        $courseId = 0,
951
        $sessionId = 0,
952
        $groupId = 0,
953
        $isAdminReport = false,
954
        $dateRange = [],
955
        $start = 0,
956
        $limit = 0
957
    ) {
958
        $em = Database::getManager();
959
        $manager = $this->isConferenceManager();
960
961
        $conditions = [];
962
        if ($courseId || $sessionId || $groupId) {
963
            $conditions = array(
964
                'where' => array(
965
                    'c_id = ? AND session_id = ? ' => array($courseId, $sessionId),
966
                ),
967
            );
968
969
            if ($this->hasGroupSupport()) {
970
                $conditions = array(
971
                    'where' => array(
972
                        'c_id = ? AND session_id = ? AND group_id = ? ' => array(
973
                            $courseId,
974
                            $sessionId,
975
                            $groupId,
976
                        ),
977
                    ),
978
                );
979
            }
980
981
            if ($this->isGlobalConferencePerUserEnabled()) {
982
                $conditions = array(
983
                    'where' => array(
984
                        'c_id = ? AND session_id = ? AND user_id = ?' => array(
985
                            $courseId,
986
                            $sessionId,
987
                            $this->userId,
988
                        ),
989
                    ),
990
                );
991
            }
992
	}
993
        if ($this->isGlobalConference()) {
994
            $conditions = array(
995
                'where' => array(
996
                    'c_id = ? AND user_id = ?' => array(
997
                        0,
998
                        $this->userId,
999
                     ),
1000
                 ),
1001
            );
1002
        }
1003
1004
        if (!empty($dateRange)) {
1005
            $dateStart = date_create($dateRange['search_meeting_start']);
1006
            $dateStart = date_format($dateStart, 'Y-m-d H:i:s');
1007
            $dateEnd = date_create($dateRange['search_meeting_end']);
1008
            $dateEnd = $dateEnd->add(new DateInterval('P1D'));
1009
            $dateEnd = date_format($dateEnd, 'Y-m-d H:i:s');
1010
1011
            $conditions = array(
1012
                'where' => array(
1013
                    'created_at BETWEEN ? AND ? ' => array($dateStart, $dateEnd),
1014
                ),
1015
            );
1016
        }
1017
1018
        $conditions['order'] = 'created_at ASC';
1019
1020
        if ($limit) {
1021
            $conditions['limit'] = "$start , $limit";
1022
        }
1023
1024
        $meetingList = Database::select(
1025
            '*',
1026
            $this->table,
1027
            $conditions
1028
        );
1029
        $isGlobal = $this->isGlobalConference();
1030
        $newMeetingList = array();
1031
        foreach ($meetingList as $meetingDB) {
1032
            $item = array();
1033
            $courseId = $meetingDB['c_id'];
1034
            $courseInfo = api_get_course_info_by_id($courseId);
1035
            $courseCode = '';
1036
            if (!empty($courseInfo)) {
1037
                $courseCode = $courseInfo['code'];
1038
            }
1039
1040
            if ($manager) {
1041
                $pass = $meetingDB['moderator_pw'];
1042
            } else {
1043
                $pass = $meetingDB['attendee_pw'];
1044
            }
1045
1046
            $meetingBBB = $this->getMeetingInfo(
1047
                [
1048
                    'meetingId' => $meetingDB['remote_id'],
1049
                    'password' => $pass,
1050
                ]
1051
            );
1052
1053
            if ($meetingBBB === false) {
1054
                // Checking with the remote_id didn't work, so just in case and
1055
                // to provide backwards support, check with the id
1056
                $params = array(
1057
                    'meetingId' => $meetingDB['id'],
1058
                    //  -- REQUIRED - The unique id for the meeting
1059
                    'password' => $pass
1060
                    //  -- REQUIRED - The moderator password for the meeting
1061
                );
1062
                $meetingBBB = $this->getMeetingInfo($params);
1063
            }
1064
1065
            if ($meetingDB['visibility'] == 0 && $this->isConferenceManager() === false) {
1066
                continue;
1067
            }
1068
1069
            $meetingBBB['end_url'] = $this->endUrl($meetingDB);
1070
1071
            if (isset($meetingBBB['returncode']) && (string) $meetingBBB['returncode'] === 'FAILED') {
1072
                if ($meetingDB['status'] == 1 && $this->isConferenceManager()) {
1073
                    $this->endMeeting($meetingDB['id'], $courseCode);
1074
                }
1075
            } else {
1076
                $meetingBBB['add_to_calendar_url'] = $this->addToCalendarUrl($meetingDB);
1077
            }
1078
1079
            if ($meetingDB['record'] == 1) {
1080
                // backwards compatibility (when there was no remote ID)
1081
                $mId = $meetingDB['remote_id'];
1082
                if (empty($mId)) {
1083
                    $mId = $meetingDB['id'];
1084
                }
1085
                if (empty($mId)) {
1086
                    // if the id is still empty (should *never* occur as 'id' is
1087
                    // the table's primary key), skip this conference
1088
                    continue;
1089
                }
1090
1091
                $record = [];
1092
                $recordingParams = ['meetingId' => $mId];
1093
                $records = $this->api->getRecordingsWithXmlResponseArray($recordingParams);
1094
1095
                if (!empty($records)) {
1096
                    if (!isset($records['messageKey']) || $records['messageKey'] !== 'noRecordings') {
1097
                        $record = end($records);
1098
                        if (!is_array($record) || !isset($record['recordId'])) {
1099
                            continue;
1100
                        }
1101
1102
                        if (!empty($record['playbackFormat'])) {
1103
                            $this->updateMeetingVideoUrl($meetingDB['id'], $record['playbackFormatUrl']);
1104
                        }
1105
                    }
1106
                }
1107
1108
                if (isset($record['playbackFormat']) && !empty($record['playbackFormat'])) {
1109
                    $recordLink = [];
1110
                    foreach ($record['playbackFormat'] as $format) {
1111
                        $this->insertMeetingFormat(intval($meetingDB['id']), $format->type->__toString(), $format->url->__toString());
1112
                        $recordLink['record'][] = 1;
1113
                        $recordLink[] = Display::url(
1114
                            $this->plugin->get_lang($format->type->__toString()),
1115
                            $format->url->__toString(),
1116
                            ['target' => '_blank', 'class' => 'btn btn-default']
1117
                        );
1118
                    }
1119
                } else {
1120
                    $recordLink = $this->plugin->get_lang('NoRecording');
1121
                }
1122
1123
                if ($isAdminReport) {
1124
                    $this->forceCIdReq(
1125
                        $courseInfo['code'],
1126
                        $meetingDB['session_id'],
1127
                        $meetingDB['group_id']
1128
                    );
1129
                }
1130
1131
                $actionLinks = $this->getActionLinks(
1132
                    $meetingDB,
1133
                    $record,
1134
                    $isGlobal,
1135
                    $isAdminReport
1136
                );
1137
                $item['show_links'] = $recordLink;
1138
                $item['record'] = true;
1139
            } else {
1140
                $actionLinks = $this->getActionLinks(
1141
                    $meetingDB,
1142
                    [],
1143
                    $isGlobal,
1144
                    $isAdminReport
1145
                );
1146
1147
                $item['show_links'] = $this->plugin->get_lang('NoRecording');
1148
                $item['record'] = false;
1149
            }
1150
1151
            $item['action_links'] = implode(PHP_EOL, $actionLinks);
1152
            $item['created_at'] = api_convert_and_format_date($meetingDB['created_at']);
1153
            // created_at
1154
            $meetingDB['created_at'] = $item['created_at']; //avoid overwrite in array_merge() below
1155
1156
            $item['closed_at'] = '';
1157
            if (!empty($meetingDB['closed_at'])) {
1158
                $item['closed_at'] = api_convert_and_format_date($meetingDB['closed_at']);
1159
                $meetingDB['closed_at'] = $item['closed_at'];
1160
            }
1161
1162
            $item['publish_url'] = $this->publishUrl($meetingDB);
1163
            $item['unpublish_url'] = $this->unPublishUrl($meetingBBB);
1164
1165
            if ($meetingDB['status'] == 1) {
1166
                $joinParams = [
1167
                    'meetingId' => $meetingDB['remote_id'],
1168
                    //-- REQUIRED - A unique id for the meeting
1169
                    'username' => $this->userCompleteName,
1170
                    //-- REQUIRED - The name that will display for the user in the meeting
1171
                    'password' => $pass,
1172
                    //-- REQUIRED - The attendee or moderator password, depending on what's passed here
1173
                    'createTime' => '',
1174
                    //-- OPTIONAL - string. Leave blank ('') unless you set this correctly.
1175
                    'userID' => '',
1176
                    //	-- OPTIONAL - string
1177
                    'webVoiceConf' => '',
1178
                ];
1179
                $item['go_url'] = $this->protocol.$this->api->getJoinMeetingURL($joinParams);
1180
            }
1181
            $item = array_merge($item, $meetingDB, $meetingBBB);
1182
1183
            $item['course'] = $em->find('ChamiloCoreBundle:Course', $item['c_id']);
1184
            $item['session'] = $em->find('ChamiloCoreBundle:Session', $item['session_id']);
1185
            $newMeetingList[] = $item;
1186
        }
1187
1188
        return $newMeetingList;
1189
    }
1190
1191
    /**
1192
     * Counts all the course meetings saved in the plugin_bbb_meeting table.
1193
     *
1194
     * @param int   $courseId
1195
     * @param int   $sessionId
1196
     * @param int   $groupId
1197
     * @param array $dateRange
1198
     *
1199
     * @return int Count of meetings
1200
     * @throws Exception
1201
     */
1202
    public function getCountMeetings(
1203
        $courseId = 0,
1204
        $sessionId = 0,
1205
        $groupId = 0,
1206
        $dateRange = []
1207
    ) {
1208
        $conditions = [];
1209
        if ($courseId || $sessionId || $groupId) {
1210
            $conditions = array(
1211
                'where' => array(
1212
                    'c_id = ? AND session_id = ? ' => array($courseId, $sessionId),
1213
                ),
1214
            );
1215
1216
            if ($this->hasGroupSupport()) {
1217
                $conditions = array(
1218
                    'where' => array(
1219
                        'c_id = ? AND session_id = ? AND group_id = ? ' => array(
1220
                            $courseId,
1221
                            $sessionId,
1222
                            $groupId,
1223
                        ),
1224
                    ),
1225
                );
1226
            }
1227
1228
            if ($this->isGlobalConferencePerUserEnabled()) {
1229
                $conditions = array(
1230
                    'where' => array(
1231
                        'c_id = ? AND session_id = ? AND user_id = ?' => array(
1232
                            $courseId,
1233
                            $sessionId,
1234
                            $this->userId,
1235
                        ),
1236
                    ),
1237
                );
1238
            }
1239
        }
1240
1241
        if (!empty($dateRange)) {
1242
            $dateStart = date_create($dateRange['search_meeting_start']);
1243
            $dateStart = date_format($dateStart, 'Y-m-d H:i:s');
1244
            $dateEnd = date_create($dateRange['search_meeting_end']);
1245
            $dateEnd = $dateEnd->add(new DateInterval('P1D'));
1246
            $dateEnd = date_format($dateEnd, 'Y-m-d H:i:s');
1247
1248
            $conditions = array(
1249
                'where' => array(
1250
                    'created_at BETWEEN ? AND ? ' => array($dateStart, $dateEnd),
1251
                ),
1252
            );
1253
        }
1254
1255
        $row = Database::select(
1256
            'count(*) as count',
1257
            $this->table,
1258
            $conditions,
1259
            'first'
1260
        );
1261
1262
        return $row['count'];
1263
    }
1264
1265
    /**
1266
     * @param array $meeting
1267
     *
1268
     * @return string
1269
     */
1270
    public function endUrl($meeting)
1271
    {
1272
        if (!isset($meeting['id'])) {
1273
            return '';
1274
        }
1275
1276
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=end&id='.$meeting['id'];
1277
    }
1278
1279
    /**
1280
     * Closes a meeting (usually when the user click on the close button from
1281
     * the conferences listing.
1282
     *
1283
     * @param string The internal ID of the meeting (id field for this meeting)
1284
     * @param string $courseCode
1285
     *
1286
     * @return void
1287
     * @assert (0) === false
1288
     */
1289
    public function endMeeting($id, $courseCode = null)
1290
    {
1291
        if (empty($id)) {
1292
            return false;
1293
        }
1294
1295
        $meetingData = Database::select(
1296
            '*',
1297
            $this->table,
1298
            array('where' => array('id = ?' => array($id))),
1299
            'first'
1300
        );
1301
        $manager = $this->isConferenceManager();
1302
        if ($manager) {
1303
            $pass = $meetingData['moderator_pw'];
1304
        } else {
1305
            $pass = $meetingData['attendee_pw'];
1306
        }
1307
1308
        Event::addEvent(
1309
            'bbb_end_meeting',
1310
            'meeting_id',
1311
            (int) $id,
1312
            null,
1313
            api_get_user_id(),
1314
            api_get_course_int_id(),
1315
            api_get_session_id()
1316
        );
1317
1318
        $endParams = array(
1319
            'meetingId' => $meetingData['remote_id'], // REQUIRED - We have to know which meeting to end.
1320
            'password' => $pass, // REQUIRED - Must match moderator pass for meeting.
1321
        );
1322
        $this->api->endMeetingWithXmlResponseArray($endParams);
1323
        Database::update(
1324
            $this->table,
1325
            array('status' => 0, 'closed_at' => api_get_utc_datetime()),
1326
            array('id = ? ' => $id)
1327
        );
1328
1329
        // Update users with in_at y ou_at field equal
1330
        $roomTable = Database::get_main_table('plugin_bbb_room');
1331
        $conditions['where'] = ['meeting_id=? AND in_at=out_at AND close=?' => [$id, BBBPlugin::ROOM_OPEN]];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$conditions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $conditions = array(); before regardless.
Loading history...
1332
        $roomList = Database::select(
1333
            '*',
1334
            $roomTable,
1335
            $conditions
1336
        );
1337
1338
        foreach ($roomList as $roomDB) {
1339
            $roomId = $roomDB['id'];
1340
            if (!empty($roomId)) {
1341
                Database::update(
1342
                    $roomTable,
1343
                    ['out_at' => api_get_utc_datetime(), 'close' => BBBPlugin::ROOM_CLOSE],
1344
                    ['id = ? ' => $roomId]
1345
                );
1346
            }
1347
        }
1348
1349
        // Close all meeting rooms with meeting ID
1350
        Database::update(
1351
            $roomTable,
1352
            ['close' => BBBPlugin::ROOM_CLOSE],
1353
            ['meeting_id = ? ' => $id]
1354
        );
1355
    }
1356
1357
    /**
1358
     * @param array $meeting
1359
     * @param array $record
1360
     *
1361
     * @return string
1362
     */
1363
    public function addToCalendarUrl($meeting, $record = [])
1364
    {
1365
        $url = isset($record['playbackFormatUrl']) ? $record['playbackFormatUrl'] : '';
1366
1367
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams(
1368
            ).'&action=add_to_calendar&id='.$meeting['id'].'&start='.api_strtotime($meeting['created_at']).'&url='.$url;
1369
    }
1370
1371
    /**
1372
     * @param int    $meetingId
1373
     * @param string $videoUrl
1374
     *
1375
     * @return bool|int
1376
     */
1377
    public function updateMeetingVideoUrl($meetingId, $videoUrl)
1378
    {
1379
        return Database::update(
1380
            'plugin_bbb_meeting',
1381
            ['video_url' => $videoUrl],
1382
            ['id = ?' => intval($meetingId)]
1383
        );
1384
    }
1385
1386
    /**
1387
     * @param int $meetingId
1388
     * @param string $formatType
1389
     * @param string $resourceUrl
1390
     *
1391
     * @return bool|int
1392
     */
1393
    public function insertMeetingFormat(int $meetingId, string $formatType, string $resourceUrl)
1394
    {
1395
        $em = Database::getManager();
1396
        $sm = $em->getConnection()->getSchemaManager();
1397
        if ($sm->tablesExist('plugin_bbb_meeting_format')) {
1398
            return Database::insert(
1399
                'plugin_bbb_meeting_format',
1400
                [
1401
                    'format_type' => $formatType,
1402
                    'resource_url' => $resourceUrl,
1403
                    'meeting_id' => $meetingId
1404
                ]
1405
            );
1406
        }
1407
1408
    }
1409
1410
    /**
1411
     * Force the course, session and/or group IDs
1412
     *
1413
     * @param string $courseCode
1414
     * @param int    $sessionId
1415
     * @param int    $groupId
1416
     */
1417
    public function forceCIdReq($courseCode, $sessionId = 0, $groupId = 0)
1418
    {
1419
        $this->courseCode = $courseCode;
1420
        $this->sessionId = (int) $sessionId;
1421
        $this->groupId = (int) $groupId;
1422
    }
1423
1424
    /**
1425
     * @param array $meetingInfo
1426
     * @param array $recordInfo
1427
     * @param bool  $isGlobal
1428
     * @param bool  $isAdminReport
1429
     *
1430
     * @return array
1431
     */
1432
    private function getActionLinks(
1433
        $meetingInfo,
1434
        $recordInfo,
1435
        $isGlobal = false,
1436
        $isAdminReport = false
1437
    ) {
1438
        $isVisible = $meetingInfo['visibility'] != 0;
1439
        $linkVisibility = $isVisible
1440
            ? Display::url(
1441
                Display::return_icon('visible.png', get_lang('MakeInvisible')),
1442
                $this->unPublishUrl($meetingInfo)
1443
            )
1444
            : Display::url(
1445
                Display::return_icon('invisible.png', get_lang('MakeVisible')),
1446
                $this->publishUrl($meetingInfo)
1447
            );
1448
1449
        $links = [];
1450
        if ($this->plugin->get('allow_regenerate_recording') === 'true' && $meetingInfo['record'] == 1) {
1451
            if (!empty($recordInfo)) {
1452
                $links[] = Display::url(
1453
                    Display::return_icon('reload.png', get_lang('RegenerateRecord')),
1454
                    $this->regenerateRecordUrl($meetingInfo, $recordInfo)
1455
                );
1456
            } else {
1457
                $links[] = Display::url(
1458
                    Display::return_icon('reload.png', get_lang('RegenerateRecord')),
1459
                    $this->regenerateRecordUrlFromMeeting($meetingInfo)
1460
                );
1461
            }
1462
        }
1463
1464
        if (empty($recordInfo)) {
1465
            if (!$isAdminReport) {
1466
                if ($meetingInfo['status'] == 0) {
1467
                    $links[] = Display::url(
1468
                        Display::return_icon('delete.png', get_lang('Delete')),
1469
                        $this->deleteRecordUrl($meetingInfo)
1470
                    );
1471
                    $links[] = $linkVisibility;
1472
                }
1473
1474
                return $links;
1475
            } else {
1476
                $links[] = Display::url(
1477
                    Display::return_icon('course_home.png', get_lang('GoToCourse')),
1478
                    $this->getListingUrl($meetingInfo['c_id'], $meetingInfo['session_id'], $meetingInfo['group_id'])
1479
                );
1480
1481
                return $links;
1482
            }
1483
        }
1484
1485
        if (!$isGlobal) {
1486
            $links[] = Display::url(
1487
                Display::return_icon('link.gif', get_lang('UrlMeetingToShare')),
1488
                $this->copyToRecordToLinkTool($meetingInfo)
1489
            );
1490
            $links[] = Display::url(
1491
                Display::return_icon('agenda.png', get_lang('AddToCalendar')),
1492
                $this->addToCalendarUrl($meetingInfo, $recordInfo)
1493
            );
1494
        }
1495
1496
        $hide = $this->plugin->get('disable_download_conference_link') === 'true' ? true : false;
1497
1498
        if ($hide == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1499
            if ($meetingInfo['has_video_m4v']) {
1500
                $links[] = Display::url(
1501
                    Display::return_icon('save.png', get_lang('DownloadFile')),
1502
                    $recordInfo['playbackFormatUrl'].'/capture.m4v',
1503
                    ['target' => '_blank']
1504
                );
1505
            } else {
1506
                $links[] = Display::url(
1507
                    Display::return_icon('save.png', get_lang('DownloadFile')),
1508
                    '#',
1509
                    [
1510
                        'id' => "btn-check-meeting-video-{$meetingInfo['id']}",
1511
                        'class' => 'check-meeting-video',
1512
                        'data-id' => $meetingInfo['id'],
1513
                    ]
1514
                );
1515
            }
1516
        }
1517
1518
1519
        if (!$isAdminReport) {
1520
            $links[] = Display::url(
1521
                Display::return_icon('delete.png', get_lang('Delete')),
1522
                $this->deleteRecordUrl($meetingInfo)
1523
            );
1524
            $links[] = $linkVisibility;
1525
        } else {
1526
            $links[] = Display::url(
1527
                Display::return_icon('course_home.png', get_lang('GoToCourse')),
1528
                $this->getListingUrl($meetingInfo['c_id'], $meetingInfo['session_id'], $meetingInfo['group_id'])
1529
            );
1530
        }
1531
1532
1533
        return $links;
1534
    }
1535
1536
    /**
1537
     * @param array $meeting
1538
     *
1539
     * @return string
1540
     */
1541
    public function unPublishUrl($meeting)
1542
    {
1543
        if (!isset($meeting['id'])) {
1544
            return null;
1545
        }
1546
1547
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams(
1548
            ).'&action=unpublish&id='.$meeting['id'];
1549
    }
1550
1551
    /**
1552
     * @param array $meeting
1553
     *
1554
     * @return string
1555
     */
1556
    public function publishUrl($meeting)
1557
    {
1558
        if (!isset($meeting['id'])) {
1559
            return '';
1560
        }
1561
1562
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams(
1563
            ).'&action=publish&id='.$meeting['id'];
1564
    }
1565
1566
    /**
1567
     * @param array $meeting
1568
     * @param array $recordInfo
1569
     *
1570
     * @return string
1571
     */
1572
    public function regenerateRecordUrl($meeting, $recordInfo)
1573
    {
1574
        if ($this->plugin->get('allow_regenerate_recording') !== 'true') {
1575
            return '';
1576
        }
1577
1578
        if (!isset($meeting['id'])) {
1579
            return '';
1580
        }
1581
1582
        if (empty($recordInfo) || (!empty($recordInfo['recordId']) && !isset($recordInfo['recordId']))) {
1583
            return '';
1584
        }
1585
1586
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().
1587
            '&action=regenerate_record&id='.$meeting['id'].'&record_id='.$recordInfo['recordId'];
1588
    }
1589
1590
    /**
1591
     * @param array $meeting
1592
     *
1593
     * @return string
1594
     */
1595
    public function regenerateRecordUrlFromMeeting($meeting)
1596
    {
1597
        if ($this->plugin->get('allow_regenerate_recording') !== 'true') {
1598
            return '';
1599
        }
1600
1601
        if (!isset($meeting['id'])) {
1602
            return '';
1603
        }
1604
1605
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().
1606
            '&action=regenerate_record&id='.$meeting['id'];
1607
    }
1608
1609
    /**
1610
     * @param array $meeting
1611
     *
1612
     * @return string
1613
     */
1614
    public function deleteRecordUrl($meeting)
1615
    {
1616
        if (!isset($meeting['id'])) {
1617
            return '';
1618
        }
1619
1620
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams(
1621
            ).'&action=delete_record&id='.$meeting['id'];
1622
    }
1623
1624
    /**
1625
     * @param array $meeting
1626
     *
1627
     * @return string
1628
     */
1629
    public function copyToRecordToLinkTool($meeting)
1630
    {
1631
        if (!isset($meeting['id'])) {
1632
            return '';
1633
        }
1634
1635
        return api_get_path(WEB_PLUGIN_PATH).
1636
            'bbb/listing.php?'.$this->getUrlParams().'&action=copy_record_to_link_tool&id='.$meeting['id'];
1637
    }
1638
1639
    /**
1640
     * Function disabled
1641
     */
1642
    public function publishMeeting($id)
1643
    {
1644
        //return BigBlueButtonBN::setPublishRecordings($id, 'true', $this->url, $this->salt);
1645
        if (empty($id)) {
1646
            return false;
1647
        }
1648
        $id = intval($id);
1649
        Database::update($this->table, array('visibility' => 1), array('id = ? ' => $id));
1650
1651
        return true;
1652
    }
1653
1654
    /**
1655
     * Function disabled
1656
     */
1657
    public function unpublishMeeting($id)
1658
    {
1659
        //return BigBlueButtonBN::setPublishRecordings($id, 'false', $this->url, $this->salt);
1660
        if (empty($id)) {
1661
            return false;
1662
        }
1663
        $id = intval($id);
1664
        Database::update($this->table, array('visibility' => 0), array('id = ?' => $id));
1665
1666
        return true;
1667
    }
1668
1669
    /**
1670
     * Get users online in the current course room.
1671
     *
1672
     * @return int The number of users currently connected to the videoconference
1673
     * @assert () > -1
1674
     */
1675
    public function getUsersOnlineInCurrentRoom()
1676
    {
1677
        $courseId = api_get_course_int_id();
1678
        $sessionId = api_get_session_id();
1679
1680
        $conditions = array(
1681
            'where' => array(
1682
                'c_id = ? AND session_id = ? AND status = 1 AND access_url = ?' => array(
1683
                    $courseId,
1684
                    $sessionId,
1685
                    $this->accessUrl,
1686
                ),
1687
            ),
1688
        );
1689
1690
        if ($this->hasGroupSupport()) {
1691
            $groupId = api_get_group_id();
1692
            $conditions = array(
1693
                'where' => array(
1694
                    'c_id = ? AND session_id = ? AND group_id = ? AND status = 1 AND access_url = ?' => array(
1695
                        $courseId,
1696
                        $sessionId,
1697
                        $groupId,
1698
                        $this->accessUrl,
1699
                    ),
1700
                ),
1701
            );
1702
        }
1703
1704
        if ($this->isGlobalConferencePerUserEnabled()) {
1705
            $conditions = array(
1706
                'where' => array(
1707
                    'user_id = ? AND status = 1 AND access_url = ?' => array(
1708
                        $this->userId,
1709
                        $this->accessUrl,
1710
                    ),
1711
                ),
1712
            );
1713
        }
1714
1715
        $meetingData = Database::select(
1716
            '*',
1717
            $this->table,
1718
            $conditions,
1719
            'first'
1720
        );
1721
1722
        if (empty($meetingData)) {
1723
            return 0;
1724
        }
1725
        $pass = $meetingData['moderator_pw'];
1726
        $info = $this->getMeetingInfo(array('meetingId' => $meetingData['remote_id'], 'password' => $pass));
1727
        if ($info === false) {
1728
            //checking with the remote_id didn't work, so just in case and
1729
            // to provide backwards support, check with the id
1730
            $params = array(
1731
                'meetingId' => $meetingData['id'],
1732
                //  -- REQUIRED - The unique id for the meeting
1733
                'password' => $pass
1734
                //  -- REQUIRED - The moderator password for the meeting
1735
            );
1736
            $info = $this->getMeetingInfo($params);
1737
        }
1738
1739
        if (!empty($info) && isset($info['participantCount'])) {
1740
            return $info['participantCount'];
1741
        }
1742
1743
        return 0;
1744
    }
1745
1746
    /**
1747
     * @param int    $id
1748
     * @param string $recordId
1749
     *
1750
     * @return bool
1751
     */
1752
    public function regenerateRecording($id, $recordId = '')
1753
    {
1754
        if ($this->plugin->get('allow_regenerate_recording') !== 'true') {
1755
            return false;
1756
        }
1757
1758
        if (empty($id)) {
1759
            return false;
1760
        }
1761
1762
        $meetingData = Database::select(
1763
            '*',
1764
            $this->table,
1765
            array('where' => array('id = ?' => array($id))),
1766
            'first'
1767
        );
1768
1769
        Event::addEvent(
1770
            'bbb_regenerate_record',
1771
            'record_id',
1772
            (int) $recordId,
1773
            null,
1774
            api_get_user_id(),
1775
            api_get_course_int_id(),
1776
            api_get_session_id()
1777
        );
1778
1779
        // Check if there are recordings for this meeting
1780
        $recordings = $this->api->getRecordings(['meetingId' => $meetingData['remote_id']]);
1781
        if (!empty($recordings) && isset($recordings['messageKey']) && $recordings['messageKey'] === 'noRecordings') {
1782
            // Regenerate the meeting id
1783
            if (!empty($meetingData['internal_meeting_id'])) {
1784
                return $this->api->generateRecording(['recordId' => $meetingData['internal_meeting_id']]);
1785
            }
1786
1787
            /*$pass = $this->getModMeetingPassword();
1788
            $info = $this->getMeetingInfo(['meetingId' => $meetingData['remote_id'], 'password' => $pass]);
1789
            if (!empty($info) && isset($info['internalMeetingID'])) {
1790
                return $this->api->generateRecording(['recordId' => $meetingData['internal_meeting_id']]);
1791
            }*/
1792
1793
            return false;
1794
        } else {
1795
            if (!empty($recordings['records'])) {
1796
                $recordExists = false;
1797
                foreach ($recordings['records'] as $record) {
1798
                    if ($recordId == $record['recordId']) {
1799
                        $recordExists = true;
1800
                        break;
1801
                    }
1802
                }
1803
1804
                if ($recordExists) {
1805
                    return $this->api->generateRecording(['recordId' => $recordId]);
1806
                }
1807
            }
1808
        }
1809
1810
        return false;
1811
    }
1812
1813
    /**
1814
     * Deletes a recording of a meeting
1815
     *
1816
     * @param int $id ID of the recording
1817
     *
1818
     * @return bool
1819
     *
1820
     * @assert () === false
1821
     * @todo Also delete links and agenda items created from this recording
1822
     */
1823
    public function deleteRecording($id)
1824
    {
1825
        if (empty($id)) {
1826
            return false;
1827
        }
1828
1829
        $meetingData = Database::select(
1830
            '*',
1831
            $this->table,
1832
            array('where' => array('id = ?' => array($id))),
1833
            'first'
1834
        );
1835
1836
        Event::addEvent(
1837
            'bbb_delete_record',
1838
            'meeting_id',
1839
            $id,
1840
            null,
1841
            api_get_user_id(),
1842
            api_get_course_int_id(),
1843
            api_get_session_id()
1844
        );
1845
1846
        $delete = false;
1847
        $recordings = [];
1848
        // Check if there are recordings for this meeting
1849
        if (!empty($meetingData['remote_id'])) {
1850
            Event::addEvent(
1851
                'bbb_delete_record',
1852
                'remote_id',
1853
                $meetingData['remote_id'],
1854
                null,
1855
                api_get_user_id(),
1856
                api_get_course_int_id(),
1857
                api_get_session_id()
1858
            );
1859
            $recordings = $this->api->getRecordings(['meetingId' => $meetingData['remote_id']]);
1860
        }
1861
        if (!empty($recordings) && isset($recordings['messageKey']) && $recordings['messageKey'] == 'noRecordings') {
1862
            $delete = true;
1863
        } else {
1864
            if (!empty($recordings['records'])) {
1865
                $recordsToDelete = [];
1866
                foreach ($recordings['records'] as $record) {
1867
                    $recordsToDelete[] = $record['recordId'];
1868
                }
1869
                $delete = true;
1870
                if (!empty($recordsToDelete)) {
1871
                    $recordingParams = ['recordId' => implode(',', $recordsToDelete)];
1872
                    Event::addEvent(
1873
                        'bbb_delete_record',
1874
                        'record_id_list',
1875
                        implode(',', $recordsToDelete),
1876
                        null,
1877
                        api_get_user_id(),
1878
                        api_get_course_int_id(),
1879
                        api_get_session_id()
1880
                    );
1881
                    $result = $this->api->deleteRecordingsWithXmlResponseArray($recordingParams);
1882
                    if (!empty($result) && isset($result['deleted']) && $result['deleted'] === 'true') {
1883
                        $delete = true;
1884
                    }
1885
                }
1886
            }
1887
        }
1888
1889
        if ($delete) {
1890
            Database::delete(
1891
                'plugin_bbb_room',
1892
                array('meeting_id = ?' => array($id))
1893
            );
1894
1895
            Database::delete(
1896
                $this->table,
1897
                array('id = ?' => array($id))
1898
            );
1899
        }
1900
1901
        return $delete;
1902
    }
1903
1904
    /**
1905
     * Creates a link in the links tool from the given videoconference recording
1906
     *
1907
     * @param int $id ID of the item in the plugin_bbb_meeting table
1908
     * @param string Hash identifying the recording, as provided by the API
1909
     *
1910
     * @return mixed ID of the newly created link, or false on error
1911
     * @assert (null, null) === false
1912
     * @assert (1, null) === false
1913
     * @assert (null, 'abcdefabcdefabcdefabcdef') === false
1914
     */
1915
    public function copyRecordingToLinkTool($id)
1916
    {
1917
        if (empty($id)) {
1918
            return false;
1919
        }
1920
        //$records =  BigBlueButtonBN::getRecordingsUrl($id);
1921
        $meetingData = Database::select(
1922
            '*',
1923
            $this->table,
1924
            array('where' => array('id = ?' => array($id))),
1925
            'first'
1926
        );
1927
1928
        $records = $this->api->getRecordingsWithXmlResponseArray(
1929
            array('meetingId' => $meetingData['remote_id'])
1930
        );
1931
1932
        if (!empty($records)) {
1933
            if (isset($records['message']) && !empty($records['message'])) {
1934
                if ($records['messageKey'] == 'noRecordings') {
1935
                    $recordArray[] = $this->plugin->get_lang('NoRecording');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$recordArray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $recordArray = array(); before regardless.
Loading history...
1936
                } else {
1937
                    //$recordArray[] = $records['message'];
1938
                }
1939
1940
                return false;
1941
            } else {
1942
                $record = $records[0];
1943
                if (is_array($record) && isset($record['recordId'])) {
1944
                    $url = $record['playbackFormatUrl'];
1945
                    $link = new Link();
1946
                    $params['url'] = $url;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.
Loading history...
1947
                    $params['title'] = $meetingData['meeting_name'];
1948
                    $id = $link->save($params);
1949
1950
                    return $id;
1951
                }
1952
            }
1953
        }
1954
1955
        return false;
1956
    }
1957
1958
    /**
1959
     * Checks if the video conference server is running.
1960
     * Function currently disabled (always returns 1)
1961
     * @return bool True if server is running, false otherwise
1962
     * @assert () === false
1963
     */
1964
    public function isServerRunning()
1965
    {
1966
        return true;
1967
        //return BigBlueButtonBN::isServerRunning($this->protocol.$this->url);
1968
    }
1969
1970
    /**
1971
     * Checks if the video conference plugin is properly configured
1972
     * @return bool True if plugin has a host and a salt, false otherwise
1973
     * @assert () === false
1974
     */
1975
    public function isServerConfigured()
1976
    {
1977
        $host = $this->plugin->get('host');
1978
1979
        if (empty($host)) {
1980
            return false;
1981
        }
1982
1983
        $salt = $this->plugin->get('salt');
1984
1985
        if (empty($salt)) {
1986
            return false;
1987
        }
1988
1989
        return true;
1990
        //return BigBlueButtonBN::isServerRunning($this->protocol.$this->url);
1991
    }
1992
1993
    /**
1994
     * Get active session in the all platform
1995
     */
1996
    public function getActiveSessionsCount()
1997
    {
1998
        $meetingList = Database::select(
1999
            'count(id) as count',
2000
            $this->table,
2001
            array('where' => array('status = ? AND access_url = ?' => array(1, $this->accessUrl))),
2002
            'first'
2003
        );
2004
2005
        return $meetingList['count'];
2006
    }
2007
2008
    /**
2009
     * Get active session in the all platform
2010
     *
2011
     * @param boolean $allSites Parameter to indicate whether to get the result from all sites
2012
     *
2013
     * @return array
2014
     */
2015
    public function getActiveSessions(bool $allSites = false): array
2016
    {
2017
        $where = ['where' => ['status = ?' => 1]];
2018
2019
        if (!$allSites) {
2020
            $where['where'][' AND access_url = ?'] = $this->accessUrl;
2021
        }
2022
2023
        return Database::select(
2024
            '*',
2025
            $this->table,
2026
            $where
2027
        );
2028
    }
2029
2030
    /**
2031
     * @param string $url
2032
     */
2033
    public function redirectToBBB($url)
2034
    {
2035
        if (file_exists(__DIR__.'/../config.vm.php')) {
2036
            // Using VM
2037
            echo Display::url($this->plugin->get_lang('ClickToContinue'), $url);
2038
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2039
        } else {
2040
            // Classic
2041
            header("Location: $url");
2042
            exit;
2043
        }
2044
    }
2045
2046
    /**
2047
     * @return string
2048
     */
2049
    public function getConferenceUrl()
2050
    {
2051
        return api_get_path(WEB_PLUGIN_PATH).'bbb/start.php?launch=1&'.$this->getUrlParams();
2052
    }
2053
2054
    /**
2055
     * Get the meeting info from DB by its name
2056
     *
2057
     * @param string $name
2058
     *
2059
     * @return array
2060
     */
2061
    public function findMeetingByName($name)
2062
    {
2063
        $meetingData = Database::select(
2064
            '*',
2065
            'plugin_bbb_meeting',
2066
            array('where' => array('meeting_name = ? AND status = 1 ' => $name)),
2067
            'first'
2068
        );
2069
2070
        return $meetingData;
2071
    }
2072
2073
    /**
2074
     * Get the meeting info from DB by its name
2075
     *
2076
     * @param int $id
2077
     *
2078
     * @return array
2079
     */
2080
    public function getMeeting($id)
2081
    {
2082
        $meetingData = Database::select(
2083
            '*',
2084
            'plugin_bbb_meeting',
2085
            array('where' => array('id = ?' => $id)),
2086
            'first'
2087
        );
2088
2089
        return $meetingData;
2090
    }
2091
2092
    /**
2093
     * Get the meeting info.
2094
     *
2095
     * @param int $id
2096
     *
2097
     * @return array
2098
     */
2099
    public function getMeetingByRemoteId($id)
2100
    {
2101
        $meetingData = Database::select(
2102
            '*',
2103
            'plugin_bbb_meeting',
2104
            array('where' => array('remote_id = ?' => $id)),
2105
            'first'
2106
        );
2107
2108
        return $meetingData;
2109
    }
2110
2111
    /**
2112
     * @param int $meetingId
2113
     *
2114
     * @return array
2115
     */
2116
    public function findConnectedMeetingParticipants($meetingId)
2117
    {
2118
        $meetingData = Database::select(
2119
            '*',
2120
            'plugin_bbb_room',
2121
            array('where' => array('meeting_id = ? AND in_at IS NOT NULL' => $meetingId))
2122
        );
2123
        $participantIds = [];
2124
        $return = [];
2125
2126
        foreach ($meetingData as $participantInfo) {
2127
            if (in_array($participantInfo['participant_id'], $participantIds)) {
2128
                continue;
2129
            }
2130
2131
            $participantIds[] = $participantInfo['participant_id'];
2132
2133
            $return[] = [
2134
                'id' => $participantInfo['id'],
2135
                'meeting_id' => $participantInfo['meeting_id'],
2136
                'participant' => api_get_user_entity($participantInfo['participant_id']),
2137
                'in_at' => $participantInfo['in_at'],
2138
                'out_at' => $participantInfo['out_at'],
2139
            ];
2140
        }
2141
2142
        return $return;
2143
    }
2144
2145
    /**
2146
     * Check if the meeting has a capture.m4v video file. If exists then the has_video_m4v field is updated
2147
     *
2148
     * @param int $meetingId
2149
     *
2150
     * @return bool
2151
     */
2152
    public function checkDirectMeetingVideoUrl($meetingId)
2153
    {
2154
        $meetingInfo = Database::select(
2155
            '*',
2156
            'plugin_bbb_meeting',
2157
            [
2158
                'where' => ['id = ?' => intval($meetingId)],
2159
            ],
2160
            'first'
2161
        );
2162
2163
        if (!isset($meetingInfo['video_url'])) {
2164
            return false;
2165
        }
2166
2167
        $hasCapture = SocialManager::verifyUrl($meetingInfo['video_url'].'/capture.m4v');
2168
2169
        if ($hasCapture) {
2170
            return Database::update(
0 ignored issues
show
Bug Best Practice introduced by
The expression return Database::update(...=> intval($meetingId))) also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
2171
                'plugin_bbb_meeting',
2172
                ['has_video_m4v' => true],
2173
                ['id = ?' => intval($meetingId)]
2174
            );
2175
        }
2176
2177
        return $hasCapture;
2178
    }
2179
}
2180