Completed
Push — 1.10.x ( 91ebd4...123d3d )
by
unknown
52:34
created

bbb::__construct()   C

Complexity

Conditions 7
Paths 48

Size

Total Lines 41
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 3
Metric Value
cc 7
eloc 26
c 3
b 0
f 3
nc 48
nop 3
dl 0
loc 41
rs 6.7272
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class bbb
6
 * This script initiates a video conference session, calling the BigBlueButton
7
 * API
8
 * @package chamilo.plugin.bigbluebutton
9
 *
10
 * BigBlueButton-Chamilo connector class
11
 */
12
//namespace Chamilo\Plugin\BBB;
13
14
/**
15
 * Class bbb
16
 * @package Chamilo\Plugin\BBB
17
 */
18
class bbb
19
{
20
    public $url;
21
    public $salt;
22
    public $api;
23
    public $user_complete_name = '';
24
    public $protocol = 'http://';
25
    public $debug = false;
26
    public $logoutUrl = '';
27
    public $pluginEnabled = false;
28
    public $enableGlobalConference = false;
29
    public $isGlobalConference = false;
30
    public $groupSupport = false;
31
32
    /**
33
     * Constructor (generates a connection to the API and the Chamilo settings
34
     * required for the connection to the video conference server)
35
     * @param string $host
36
     * @param string $salt
37
     */
38
    public function __construct($host = '', $salt = '', $isGlobalConference = false)
39
    {
40
        // Initialize video server settings from global settings
41
        $plugin = BBBPlugin::create();
42
43
        $bbbPlugin = $plugin->get('tool_enable');
44
45
        $bbb_host = !empty($host) ? $host : $plugin->get('host');
46
        $bbb_salt = !empty($salt) ? $salt : $plugin->get('salt');
47
48
        $this->logoutUrl = $this->getListingUrl();
49
        $this->table = Database::get_main_table('plugin_bbb_meeting');
50
        $this->enableGlobalConference = $plugin->get('enable_global_conference');
0 ignored issues
show
Documentation Bug introduced by
The property $enableGlobalConference was declared of type boolean, but $plugin->get('enable_global_conference') 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...
51
        $this->isGlobalConference = (bool) $isGlobalConference;
52
53
        $columns = Database::listTableColumns($this->table);
54
        $this->groupSupport = isset($columns['group_id']) ? true : false;
55
56
        if ($this->groupSupport) {
57
            $this->groupSupport = (bool) $plugin->get('enable_conference_in_course_groups');
58
        }
59
60
        if ($bbbPlugin === true) {
61
            $userInfo = api_get_user_info();
62
            $this->user_complete_name = $userInfo['complete_name'];
63
            $this->salt = $bbb_salt;
64
            $info = parse_url($bbb_host);
65
            $this->url = $bbb_host.'/bigbluebutton/';
66
            if (isset($info['scheme'])) {
67
                $this->protocol = $info['scheme'].'://';
68
                $this->url = str_replace($this->protocol, '', $this->url);
69
            }
70
71
            // Setting BBB api
72
            define('CONFIG_SECURITY_SALT', $this->salt);
73
            define('CONFIG_SERVER_BASE_URL', $this->url);
74
75
            $this->api = new BigBlueButtonBN();
76
            $this->pluginEnabled = true;
77
        }
78
    }
79
80
    /**
81
     * @return bool
82
     */
83
    public function isGlobalConferenceEnabled()
84
    {
85
        return (bool) $this->enableGlobalConference;
86
    }
87
88
    /**
89
     * @return bool
90
     */
91
    public function isGlobalConference()
92
    {
93
        if ($this->isGlobalConferenceEnabled() === false) {
94
95
            return false;
96
        }
97
98
        return (bool) $this->isGlobalConference;
99
    }
100
101
    /**
102
     * @return bool
103
     */
104
    public function hasGroupSupport()
105
    {
106
        return $this->groupSupport;
107
    }
108
109
    /**
110
     * Checks whether a user is teacher in the current course
111
     * @return bool True if the user can be considered a teacher in this course, false otherwise
112
     */
113
    public function isConferenceManager()
114
    {
115
        return api_is_course_admin() || api_is_coach() || api_is_platform_admin();
116
    }
117
118
    /**
119
     * See this file in you BBB to set up default values
120
     * @param   array $params Array of parameters that will be completed if not containing all expected variables
121
122
       /var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties
123
     *
124
       More record information:
125
       http://code.google.com/p/bigbluebutton/wiki/RecordPlaybackSpecification
126
127
       # Default maximum number of users a meeting can have.
128
        # Doesn't get enforced yet but is the default value when the create
129
        # API doesn't pass a value.
130
        defaultMaxUsers=20
131
132
        # Default duration of the meeting in minutes.
133
        # Current default is 0 (meeting doesn't end).
134
        defaultMeetingDuration=0
135
136
        # Remove the meeting from memory when the end API is called.
137
        # This allows 3rd-party apps to recycle the meeting right-away
138
        # instead of waiting for the meeting to expire (see below).
139
        removeMeetingWhenEnded=false
140
141
        # The number of minutes before the system removes the meeting from memory.
142
        defaultMeetingExpireDuration=1
143
144
        # The number of minutes the system waits when a meeting is created and when
145
        # a user joins. If after this period, a user hasn't joined, the meeting is
146
        # removed from memory.
147
        defaultMeetingCreateJoinDuration=5
148
     *
149
     */
150
    public function createMeeting($params)
151
    {
152
        $courseCode = api_get_course_id();
153
        $params['c_id'] = api_get_course_int_id();
154
        $params['session_id'] = api_get_session_id();
155
156
        if ($this->hasGroupSupport()) {
157
            $params['group_id'] = api_get_group_id();
158
        }
159
160
        $params['attendee_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $courseCode;
161
        $attendeePassword =  $params['attendee_pw'];
162
        $params['moderator_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $this->getModMeetingPassword();
163
        $moderatorPassword = $params['moderator_pw'];
164
165
        $params['record'] = api_get_course_setting('big_blue_button_record_and_store', $courseCode) == 1 ? true : false;
166
        $max = api_get_course_setting('big_blue_button_max_students_allowed', $courseCode);
167
        $max =  isset($max) ? $max : -1;
168
169
        $params['status'] = 1;
170
        // Generate a pseudo-global-unique-id to avoid clash of conferences on
171
        // the same BBB server with several Chamilo portals
172
        $params['remote_id'] = uniqid(true, true);
173
        // Each simultaneous conference room needs to have a different
174
        // voice_bridge composed of a 5 digits number, so generating a random one
175
        $params['voice_bridge'] = rand(10000, 99999);
176
177
        if ($this->debug) {
178
            error_log("enter create_meeting ".print_r($params, 1));
179
        }
180
181
        $params['created_at'] = api_get_utc_datetime();
182
        $id = Database::insert($this->table, $params);
183
184
        if ($id) {
185
            if ($this->debug) {
186
                error_log("create_meeting: $id ");
187
            }
188
189
            $meetingName = isset($params['meeting_name']) ? $params['meeting_name'] : $this->getCurrentVideoConferenceName();
190
            $welcomeMessage = isset($params['welcome_msg']) ? $params['welcome_msg'] : null;
191
            $record = isset($params['record']) && $params['record'] ? 'true' : 'false';
192
            $duration = isset($params['duration']) ? intval($params['duration']) : 0;
193
            // This setting currently limits the maximum conference duration,
194
            // to avoid lingering sessions on the video-conference server #6261
195
            $duration = 300;
196
197
            $bbbParams = array(
198
                'meetingId' => $params['remote_id'], 					// REQUIRED
199
                'meetingName' => $meetingName, 	// REQUIRED
200
                'attendeePw' => $attendeePassword, 					// Match this value in getJoinMeetingURL() to join as attendee.
201
                'moderatorPw' => $moderatorPassword, 					// Match this value in getJoinMeetingURL() to join as moderator.
202
                'welcomeMsg' => $welcomeMessage, 					// ''= use default. Change to customize.
203
                'dialNumber' => '', 					// The main number to call into. Optional.
204
                'voiceBridge' => $params['voice_bridge'], 					// PIN to join voice. Required.
205
                'webVoice' => '', 						// Alphanumeric to join voice. Optional.
206
                'logoutUrl' =>  $this->logoutUrl,
207
                'maxParticipants' => $max, 				// Optional. -1 = unlimitted. Not supported in BBB. [number]
208
                'record' => $record, 					// New. 'true' will tell BBB to record the meeting.
209
                'duration' => $duration, 				// Default = 0 which means no set duration in minutes. [number]
210
                //'meta_category' => '', 				// Use to pass additional info to BBB server. See API docs.
211
            );
212
213
            if ($this->debug) {
214
                error_log("create_meeting params: ".print_r($bbbParams,1));
215
            }
216
217
            $status = false;
218
            $meeting = null;
219
220
            while ($status === false) {
221
                $result = $this->api->createMeetingWithXmlResponseArray(
222
                    $bbbParams
223
                );
224
                if (isset($result) && strval($result['returncode']) == 'SUCCESS') {
225
                    if ($this->debug) {
226
                        error_log(
227
                            "create_meeting result: " . print_r($result, 1)
228
                        );
229
                    }
230
                    $meeting = $this->joinMeeting($meetingName, true);
231
232
                    return $meeting;
233
                }
234
            }
235
236
            return $this->logoutUrl;
237
        }
238
    }
239
240
    /**
241
     * Tells whether the given meeting exists and is running
242
     * (using course code as name)
243
     * @param string $meetingName Meeting name (usually the course code)
244
     *
245
     * @return bool True if meeting exists, false otherwise
246
     * @assert ('') === false
247
     * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
248
     */
249
    public function meetingExists($meetingName)
250
    {
251
        if (empty($meetingName)) {
252
253
            return false;
254
        }
255
256
        $courseId = api_get_course_int_id();
257
        $sessionId = api_get_session_id();
258
        $conditions =  array(
259
            'where' => array(
260
                'c_id = ? AND session_id = ? AND meeting_name = ? AND status = 1 ' =>
261
                    array($courseId, $sessionId, $meetingName)
262
            )
263
        );
264
265 View Code Duplication
        if ($this->hasGroupSupport()) {
266
            $groupId = api_get_group_id();
267
            $conditions =  array(
268
                'where' => array(
269
                    'c_id = ? AND session_id = ? AND meeting_name = ? AND group_id = ? AND status = 1 ' =>
270
                        array($courseId, $sessionId, $meetingName, $groupId)
271
                )
272
            );
273
        }
274
275
        $meetingData = Database::select(
276
            '*',
277
            $this->table,
278
            $conditions,
279
            'first'
280
        );
281
282
283
        if ($this->debug) {
284
            error_log("meeting_exists ".print_r($meetingData, 1));
285
        }
286
287
        if (empty($meetingData)) {
288
289
            return false;
290
        } else {
291
            return true;
292
        }
293
    }
294
295
    /**
296
     * Returns a meeting "join" URL
297
     * @param string The name of the meeting (usually the course code)
298
     * @return mixed The URL to join the meeting, or false on error
299
     * @todo implement moderator pass
300
     * @assert ('') === false
301
     * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
302
     */
303
    public function joinMeeting($meetingName, $loop = false)
304
    {
305
        if (empty($meetingName)) {
306
            return false;
307
        }
308
309
        $pass = $this->getUserMeetingPassword();
310
311
        $meetingData = Database::select(
312
            '*',
313
            $this->table,
314
            array('where' => array('meeting_name = ? AND status = 1 ' => $meetingName)),
315
            'first'
316
        );
317
318
        if (empty($meetingData) || !is_array($meetingData)) {
319
            if ($this->debug) {
320
                error_log("meeting does not exist: $meetingName");
321
            }
322
323
            return false;
324
        }
325
326
        $params = array(
327
            'meetingId' => $meetingData['remote_id'],
328
            //  -- REQUIRED - The unique id for the meeting
329
            'password' => $this->getModMeetingPassword()
330
            //  -- REQUIRED - The moderator password for the meeting
331
        );
332
333
        $status = false;
334
        $meetingInfoExists = false;
335
        while ($status === false) {
336
337
            $meetingIsRunningInfo = $this->getMeetingInfo($params);
338 View Code Duplication
            if ($meetingIsRunningInfo === false) {
339
                //checking with the remote_id didn't work, so just in case and
340
                // to provide backwards support, check with the id
341
                $params = array(
342
                    'meetingId' => $meetingData['id'],
343
                    //  -- REQUIRED - The unique id for the meeting
344
                    'password' => $this->getModMeetingPassword()
345
                    //  -- REQUIRED - The moderator password for the meeting
346
                );
347
                $meetingIsRunningInfo = $this->getMeetingInfo($params);
348
            }
349
350
            if ($this->debug) {
351
                error_log(print_r($meetingIsRunningInfo, 1));
352
            }
353
354
            if (strval($meetingIsRunningInfo['returncode']) == 'SUCCESS' &&
355
                isset($meetingIsRunningInfo['meetingName']) &&
356
                !empty($meetingIsRunningInfo['meetingName'])
357
                //strval($meetingIsRunningInfo['running']) == 'true'
358
            ) {
359
                $meetingInfoExists = true;
360
            }
361
362
            if ($this->debug) {
363
                error_log(
364
                    "meeting is running: " . intval($meetingInfoExists)
365
                );
366
            }
367
368
            if ($meetingInfoExists) {
369
                $status = true;
370
            }
371
372
            if ($loop) {
373
                continue;
374
            } else {
375
                break;
376
            }
377
        }
378
379
        if ($meetingInfoExists) {
380
            $joinParams = array(
381
                'meetingId' => $meetingData['remote_id'],	//	-- REQUIRED - A unique id for the meeting
382
                'username' => $this->user_complete_name,	//-- REQUIRED - The name that will display for the user in the meeting
383
                'password' => $pass,			//-- REQUIRED - The attendee or moderator password, depending on what's passed here
384
                //'createTime' => api_get_utc_datetime(),			//-- OPTIONAL - string. Leave blank ('') unless you set this correctly.
385
                'userID' => api_get_user_id(),				//-- OPTIONAL - string
386
                'webVoiceConf' => ''	//	-- OPTIONAL - string
387
            );
388
            $url = $this->api->getJoinMeetingURL($joinParams);
389
            $url = $this->protocol.$url;
390
        } else {
391
            $url = $this->logoutUrl;
392
        }
393
        if ($this->debug) {
394
            error_log("return url :" . $url);
395
        }
396
397
        return $url;
398
    }
399
400
    /**
401
     * Get information about the given meeting
402
     * @param array ...?
403
     * @return mixed Array of information on success, false on error
404
     * @assert (array()) === false
405
     */
406
    public function getMeetingInfo($params)
407
    {
408
        try {
409
            $result = $this->api->getMeetingInfoWithXmlResponseArray($params);
410
            if ($result == null) {
411
                if ($this->debug) {
412
                    error_log("Failed to get any response. Maybe we can't contact the BBB server.");
413
                }
414
            } else {
415
                return $result;
416
            }
417
        } catch (Exception $e) {
418
            if ($this->debug) {
419
                error_log('Caught exception: ', $e->getMessage(), "\n");
420
            }
421
        }
422
423
        return false;
424
    }
425
426
    /**
427
     * Gets all the course meetings saved in the plugin_bbb_meeting table
428
     * @return array Array of current open meeting rooms
429
     */
430
    public function getMeetings()
431
    {
432
        $pass = $this->getUserMeetingPassword();
433
        $courseId = api_get_course_int_id();
434
        $sessionId  = api_get_session_id();
435
436
        $conditions =  array(
437
            'where' => array(
438
                'c_id = ? AND session_id = ? ' => array(
439
                    $courseId,
440
                    $sessionId,
441
                ),
442
            ),
443
        );
444
445 View Code Duplication
        if ($this->hasGroupSupport()) {
446
            $groupId = api_get_group_id();
447
            $conditions =  array(
448
                'where' => array(
449
                    'c_id = ? AND session_id = ? AND group_id = ? ' =>
450
                        array($courseId, $sessionId, $groupId)
451
                )
452
            );
453
        }
454
455
        $meetingList = Database::select(
456
            '*',
457
            $this->table,
458
            $conditions
459
        );
460
        $isGlobal = $this->isGlobalConference();
461
        $newMeetingList = array();
462
        $item = array();
463
        foreach ($meetingList as $meetingDB) {
464
            $meetingBBB = $this->getMeetingInfo(['meetingId' => $meetingDB['remote_id'], 'password' => $pass]);
465 View Code Duplication
            if ($meetingBBB === false) {
466
                //checking with the remote_id didn't work, so just in case and
467
                // to provide backwards support, check with the id
468
                $params = array(
469
                    'meetingId' => $meetingDB['id'],
470
                    //  -- REQUIRED - The unique id for the meeting
471
                    'password' => $pass
472
                    //  -- REQUIRED - The moderator password for the meeting
473
                );
474
                $meetingBBB = $this->getMeetingInfo($params);
475
            }
476
477
            if ($meetingDB['visibility'] == 0 && $this->isConferenceManager() === false) {
478
                continue;
479
            }
480
            $meetingBBB['end_url'] = $this->endUrl($meetingDB);
481
482
            if ((string)$meetingBBB['returncode'] == 'FAILED') {
483
                if ($meetingDB['status'] == 1 && $this->isConferenceManager()) {
484
                    $this->endMeeting($meetingDB['id']);
485
                }
486
            } else {
487
                $meetingBBB['add_to_calendar_url'] = $this->addToCalendarUrl($meetingDB);
488
            }
489
490
            $recordArray = array();
491
            $actionLinksArray = array();
492
493
            if ($meetingDB['record'] == 1) {
494
                // backwards compatibility (when there was no remote ID)
495
                $mId = $meetingDB['remote_id'];
496
                if (empty($mId)) {
497
                    $mId = $meetingDB['id'];
498
                }
499
                if (empty($mId)) {
500
                    // if the id is still empty (should *never* occur as 'id' is
501
                    // the table's primary key), skip this conference
502
                    continue;
503
                }
504
                $recordingParams = array(
505
                    'meetingId' => $mId, //-- OPTIONAL - comma separate if multiple ids
506
                );
507
508
                //To see the recording list in your BBB server do: bbb-record --list
509
                $records = $this->api->getRecordingsWithXmlResponseArray($recordingParams);
510
                if (!empty($records)) {
511
                    $count = 1;
512
                    if (isset($records['message']) && !empty($records['message'])) {
513
                        if ($records['messageKey'] == 'noRecordings') {
514
                            $recordArray[] = get_lang('NoRecording');
515
                            if ($meetingDB['visibility'] == 0) {
516
                                $actionLinksArray[] = Display::url(
517
                                    Display::return_icon(
518
                                        'invisible.png',
519
                                        get_lang('MakeVisible'),
520
                                        array(),
521
                                        ICON_SIZE_MEDIUM
522
                                    ),
523
                                    $this->publishUrl($meetingDB)
524
                                );
525
                            } else {
526
                                $actionLinksArray[] = Display::url(
527
                                    Display::return_icon(
528
                                        'visible.png',
529
                                        get_lang('MakeInvisible'),
530
                                        array(),
531
                                        ICON_SIZE_MEDIUM
532
                                    ),
533
                                    $this->unPublishUrl($meetingDB)
534
                                );
535
                            }
536
                        }
537
                    } else {
538
                        foreach ($records as $record) {
539
                            //if you get several recordings here and you used a
540
                            // previous version of Chamilo, you might want to
541
                            // only keep the last result for each chamilo conf
542
                            // (see show_links after the end of this loop)
543
                            if (is_array($record) && isset($record['recordId'])) {
544
                                $url = Display::url(
545
                                    get_lang('ViewRecord')." [~".$record['playbackFormatLength']."']",
546
                                    $record['playbackFormatUrl'],
547
                                    array('target' => '_blank')
548
                                );
549
                                $actionLinks = '';
550
                                if ($this->isConferenceManager()) {
551
                                    if ($isGlobal === false) {
552
                                        $actionLinks .= Display::url(
553
                                            Display::return_icon(
554
                                                'link.gif',
555
                                                get_lang('CopyToLinkTool')
556
                                            ),
557
                                            $this->copyToRecordToLinkTool($meetingDB)
558
                                        );
559
                                        $actionLinks .= Display::url(
560
                                            Display::return_icon(
561
                                                'agenda.png',
562
                                                get_lang('AddToCalendar')
563
                                            ),
564
                                            $this->addToCalendarUrl($meetingDB, $record)
565
                                        );
566
                                    }
567
                                    $actionLinks .= Display::url(
568
                                        Display::return_icon(
569
                                            'delete.png',
570
                                            get_lang('Delete')
571
                                        ),
572
                                        $this->deleteRecordUrl($meetingDB)
573
                                    );
574
575 View Code Duplication
                                    if ($meetingDB['visibility'] == 0) {
576
                                        $actionLinks .= Display::url(
577
                                            Display::return_icon(
578
                                                'invisible.png',
579
                                                get_lang('MakeVisible'),
580
                                                array(),
581
                                                ICON_SIZE_MEDIUM
582
                                            ),
583
                                            $this->publishUrl($meetingDB)
584
                                        );
585
                                    } else {
586
                                        $actionLinks .= Display::url(
587
                                            Display::return_icon(
588
                                                'visible.png',
589
                                                get_lang('MakeInvisible'),
590
                                                array(),
591
                                                ICON_SIZE_MEDIUM
592
                                            ),
593
                                            $this->unPublishUrl($meetingDB)
594
                                        );
595
                                    }
596
                                }
597
                                $count++;
598
                                $recordArray[] = $url;
599
                                $actionLinksArray[] = $actionLinks;
600
                            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
601
                                /*if (is_array($record) && isset($record['recordID']) && isset($record['playbacks'])) {
602
603
                                    //Fix the bbb timestamp
604
                                    //$record['startTime'] = substr($record['startTime'], 0, strlen($record['startTime']) -3);
605
                                    //$record['endTime']   = substr($record['endTime'], 0, strlen($record['endTime']) -3);
606
                                    //.' - '.api_convert_and_format_date($record['startTime']).' - '.api_convert_and_format_date($record['endTime'])
607
                                    foreach($record['playbacks'] as $item) {
608
                                        $url = Display::url(get_lang('ViewRecord'), $item['url'], array('target' => '_blank'));
609
                                        //$url .= Display::url(get_lang('DeleteRecord'), api_get_self().'?action=delete_record&'.$record['recordID']);
610
                                        if ($this->isConferenceManager()) {
611
                                            $url .= Display::url(Display::return_icon('link.gif',get_lang('CopyToLinkTool')), api_get_self().'?action=copy_record_to_link_tool&id='.$meetingDB['id'].'&record_id='.$record['recordID']);
612
                                            $url .= Display::url(Display::return_icon('agenda.png',get_lang('AddToCalendar')), api_get_self().'?action=add_to_calendar&id='.$meetingDB['id'].'&start='.api_strtotime($meetingDB['created_at']).'&url='.$item['url']);
613
                                            $url .= Display::url(Display::return_icon('delete.png',get_lang('Delete')), api_get_self().'?action=delete_record&id='.$record['recordID']);
614
                                        }
615
                                        //$url .= api_get_self().'?action=publish&id='.$record['recordID'];
616
                                        $count++;
617
                                        $recordArray[] = $url;
618
                                    }
619
                                }*/
620
                            }
621
                        }
622
                    }
623
                } else {
624
                    $actionLinks = '';
625 View Code Duplication
                    if ($this->isConferenceManager()) {
626
                        if ($meetingDB['visibility'] == 0) {
627
                            $actionLinks .= Display::url(
628
                                Display::return_icon(
629
                                    'invisible.png',
630
                                    get_lang('MakeVisible'),
631
                                    array(),
632
                                    ICON_SIZE_MEDIUM
633
                                ),
634
                                $this->publishUrl($meetingDB)
635
                            );
636
                        } else {
637
                            $actionLinks .= Display::url(
638
                                Display::return_icon(
639
                                    'visible.png',
640
                                    get_lang('MakeInvisible'),
641
                                    array(),
642
                                    ICON_SIZE_MEDIUM
643
                                ),
644
                                $this->unPublishUrl($meetingDB)
645
                            );
646
                        }
647
                    }
648
                    $actionLinksArray[] = $actionLinks;
649
                    $item['action_links'] = implode('<br />', $actionLinksArray);
650
                }
651
                //var_dump($recordArray);
652
                $item['show_links']  = implode('<br />', $recordArray);
653
                $item['action_links'] = implode('<br />', $actionLinksArray);
654
            }
655
656
            $item['created_at'] = api_convert_and_format_date($meetingDB['created_at']);
657
            //created_at
658
            $meetingDB['created_at'] = $item['created_at']; //avoid overwrite in array_merge() below
659
660
            $item['publish_url'] = $this->publishUrl($meetingDB);
661
            $item['unpublish_url'] = $this->unPublishUrl($meetingBBB);
0 ignored issues
show
Security Bug introduced by
It seems like $meetingBBB can also be of type false; however, bbb::unPublishUrl() does only seem to accept array, did you maybe forget to handle an error condition?
Loading history...
662
663
            if ($meetingDB['status'] == 1) {
664
                $joinParams = array(
665
                    'meetingId' => $meetingDB['remote_id'],		//-- REQUIRED - A unique id for the meeting
666
                    'username' => $this->user_complete_name,	//-- REQUIRED - The name that will display for the user in the meeting
667
                    'password' => $pass,			//-- REQUIRED - The attendee or moderator password, depending on what's passed here
668
                    'createTime' => '',			//-- OPTIONAL - string. Leave blank ('') unless you set this correctly.
669
                    'userID' => '',			//	-- OPTIONAL - string
670
                    'webVoiceConf' => ''	//	-- OPTIONAL - string
671
                );
672
                $item['go_url'] = $this->protocol.$this->api->getJoinMeetingURL($joinParams);
673
            }
674
            $item = array_merge($item, $meetingDB, $meetingBBB);
675
            $newMeetingList[] = $item;
676
        }
677
678
        return $newMeetingList;
679
    }
680
681
    /**
682
     * Function disabled
683
     */
684 View Code Duplication
    public function publishMeeting($id)
685
    {
686
        //return BigBlueButtonBN::setPublishRecordings($id, 'true', $this->url, $this->salt);
687
        if (empty($id)) {
688
689
            return false;
690
        }
691
        $id = intval($id);
692
        Database::update($this->table, array('visibility' => 1), array('id = ? ' => $id));
693
694
        return true;
695
    }
696
697
    /**
698
     * Function disabled
699
     */
700 View Code Duplication
    public function unpublishMeeting($id)
701
    {
702
        //return BigBlueButtonBN::setPublishRecordings($id, 'false', $this->url, $this->salt);
703
        if (empty($id)) {
704
705
            return false;
706
        }
707
        $id = intval($id);
708
        Database::update($this->table, array('visibility' => 0), array('id = ?' => $id));
709
710
        return true;
711
    }
712
713
    /**
714
     * Closes a meeting (usually when the user click on the close button from
715
     * the conferences listing.
716
     * @param string The internal ID of the meeting (id field for this meeting)
717
     * @return void
718
     * @assert (0) === false
719
     */
720
    public function endMeeting($id)
721
    {
722
        if (empty($id)) {
723
724
            return false;
725
        }
726
        $meetingData = Database::select('*', $this->table, array('where' => array('id = ?' => array($id))), 'first');
727
        $pass = $this->getUserMeetingPassword();
728
729
        $endParams = array(
730
            'meetingId' => $meetingData['remote_id'],   // REQUIRED - We have to know which meeting to end.
731
            'password' => $pass,        // REQUIRED - Must match moderator pass for meeting.
732
        );
733
        $this->api->endMeetingWithXmlResponseArray($endParams);
734
        Database::update(
735
            $this->table,
736
            array('status' => 0, 'closed_at' => api_get_utc_datetime()),
737
            array('id = ? ' => $id)
738
        );
739
    }
740
741
    /**
742
     * Gets the password for a specific meeting for the current user
743
     * @return string A moderator password if user is teacher, or the course code otherwise
744
     */
745
    public function getUserMeetingPassword()
746
    {
747
        if ($this->isConferenceManager()) {
748
749
            return $this->getModMeetingPassword();
750
        } else {
751
752
            if ($this->isGlobalConference()) {
753
754
                return 'url_'.api_get_current_access_url_id();
755
            }
756
757
            return api_get_course_id();
758
        }
759
    }
760
761
    /**
762
     * Generated a moderator password for the meeting
763
     * @return string A password for the moderation of the videoconference
764
     */
765
    public function getModMeetingPassword()
766
    {
767
        if ($this->isGlobalConference()) {
768
769
            return 'url_'.api_get_current_access_url_id().'_mod';
770
        }
771
772
        return api_get_course_id().'mod';
773
    }
774
775
    /**
776
     * Get users online in the current course room
777
     * @return int The number of users currently connected to the videoconference
778
     * @assert () > -1
779
     */
780
    public function getUsersOnlineInCurrentRoom()
781
    {
782
        $courseId = api_get_course_int_id();
783
        $sessionId = api_get_session_id();
784
785
        $conditions = array(
786
            'where' => array(
787
                'c_id = ? AND session_id = ? AND status = 1 ' => array(
788
                    $courseId,
789
                    $sessionId,
790
                ),
791
            ),
792
        );
793
794 View Code Duplication
        if ($this->hasGroupSupport()) {
795
            $groupId = api_get_group_id();
796
            $conditions = array(
797
                'where' => array(
798
                    'c_id = ? AND session_id = ? AND group_id = ? AND status = 1 ' => array(
799
                        $courseId,
800
                        $sessionId,
801
                        $groupId
802
                    ),
803
                ),
804
            );
805
        }
806
        $meetingData = Database::select(
807
            '*',
808
            $this->table,
809
            $conditions,
810
            'first'
811
        );
812
813
        if (empty($meetingData)) {
814
            return 0;
815
        }
816
        $pass = $this->getModMeetingPassword();
817
        $info = $this->getMeetingInfo(array('meetingId' => $meetingData['remote_id'], 'password' => $pass));
818 View Code Duplication
        if ($info === false) {
819
            //checking with the remote_id didn't work, so just in case and
820
            // to provide backwards support, check with the id
821
            $params = array(
822
                'meetingId' => $meetingData['id'],
823
                //  -- REQUIRED - The unique id for the meeting
824
                'password' => $pass
825
                //  -- REQUIRED - The moderator password for the meeting
826
            );
827
            $info = $this->getMeetingInfo($params);
828
        }
829
830
        if (!empty($info) && isset($info['participantCount'])) {
831
            return $info['participantCount'];
832
833
        }
834
        return 0;
835
    }
836
837
    /**
838
     * Deletes a previous recording of a meeting
839
     * @param int integral ID of the recording
840
     * @return array ?
841
     * @assert () === false
842
     * @todo Also delete links and agenda items created from this recording
843
     */
844
    public function deleteRecord($id)
845
    {
846
        if (empty($id)) {
847
            return false;
848
        }
849
850
        $meetingData = Database::select(
851
            '*',
852
            $this->table,
853
            array('where' => array('id = ?' => array($id))),
854
            'first'
855
        );
856
857
        $recordingParams = array(
858
            /*
859
             * NOTE: Set the recordId below to a valid id after you have
860
             * created a recorded meeting, and received a real recordID
861
             * back from your BBB server using the
862
             * getRecordingsWithXmlResponseArray method.
863
             */
864
865
            // REQUIRED - We have to know which recording:
866
            'recordId' => $meetingData['remote_id'],
867
        );
868
869
        $result = $this->api->deleteRecordingsWithXmlResponseArray($recordingParams);
870
871
        if (!empty($result) && isset($result['deleted']) && $result['deleted'] == 'true') {
872
            Database::delete(
873
                $this->table,
874
                array('id = ?' => array($id))
875
            );
876
        }
877
878
        return $result;
879
    }
880
881
    /**
882
     * Creates a link in the links tool from the given videoconference recording
883
     * @param int ID of the item in the plugin_bbb_meeting table
884
     * @param string Hash identifying the recording, as provided by the API
885
     * @return mixed ID of the newly created link, or false on error
886
     * @assert (null, null) === false
887
     * @assert (1, null) === false
888
     * @assert (null, 'abcdefabcdefabcdefabcdef') === false
889
     */
890
    public function copyRecordToLinkTool($id)
891
    {
892
        if (empty($id)) {
893
            return false;
894
        }
895
        //$records =  BigBlueButtonBN::getRecordingsUrl($id);
896
        $meetingData = Database::select('*', $this->table, array('where' => array('id = ?' => array($id))), 'first');
897
898
        $records = $this->api->getRecordingsWithXmlResponseArray(array('meetingId' => $meetingData['remote_id']));
899
900
        if (!empty($records)) {
901
            if (isset($records['message']) && !empty($records['message'])) {
902
                if ($records['messageKey'] == 'noRecordings') {
903
                    $recordArray[] = get_lang('NoRecording');
904
                } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
905
                    //$recordArray[] = $records['message'];
906
                }
907
                return false;
908
            } else {
909
                $record = $records[0];
910
                if (is_array($record) && isset($record['recordId'])) {
911
                    $url = $record['playbackFormatUrl'];
912
                    $link = new Link();
0 ignored issues
show
Bug introduced by
The call to Link::__construct() misses some required arguments starting with $id.
Loading history...
913
                    $params['url'] = $url;
914
                    $params['title'] = $meetingData['meeting_name'];
915
                    $id = $link->save($params);
916
                    return $id;
917
                }
918
            }
919
        }
920
921
        return false;
922
    }
923
924
    /**
925
     * Checks if the videoconference server is running.
926
     * Function currently disabled (always returns 1)
927
     * @return bool True if server is running, false otherwise
928
     * @assert () === false
929
     */
930
    public function isServerRunning()
931
    {
932
        return true;
933
        //return BigBlueButtonBN::isServerRunning($this->protocol.$this->url);
934
    }
935
936
    /**
937
     * Get active session in the all platform
938
     */
939
    public function getActiveSessionsCount()
940
    {
941
        $meetingList = Database::select(
942
            'count(id) as count',
943
            $this->table,
944
            array('where' => array('status = ?' => array(1))),
945
            'first'
946
        );
947
948
        return $meetingList['count'];
949
    }
950
951
    /**
952
     * @param string $url
953
     */
954
    public function redirectToBBB($url)
955
    {
956
        if (file_exists(__DIR__ . '/../config.vm.php')) {
957
            // Using VM
958
            echo Display::url(get_lang('ClickToContinue'), $url);
959
            exit;
960
        } else {
961
            // Classic
962
            header("Location: $url");
963
            exit;
964
        }
965
966
        // js
967
        /*echo '<script>';
968
        echo 'window.location = "'.$url.'"';
969
        echo '</script>';
970
        exit;*/
971
    }
972
973
    /**
974
     * @return string
975
     */
976
    public function getUrlParams()
977
    {
978
        $courseInfo = api_get_course_info();
979
980
        if (empty($courseInfo)) {
981
982
            if ($this->isGlobalConference()) {
983
                return 'global=1';
984
            }
985
986
            return '';
987
        }
988
989
        return api_get_cidreq();
990
    }
991
992
    /**
993
     * @return string
994
     */
995
    public function getCurrentVideoConferenceName()
996
    {
997
        if ($this->isGlobalConference()) {
998
            return 'url_'.api_get_current_access_url_id();
999
        }
1000
1001
        if ($this->hasGroupSupport()) {
1002
1003
            return api_get_course_id().'-'.api_get_session_id().'-'.api_get_group_id();
1004
        }
1005
1006
        return api_get_course_id().'-'.api_get_session_id();
1007
    }
1008
1009
    /**
1010
     * @return string
1011
     */
1012
    public function getConferenceUrl()
1013
    {
1014
        return api_get_path(WEB_PLUGIN_PATH).'bbb/start.php?launch=1&'.$this->getUrlParams();
1015
    }
1016
1017
    /**
1018
     * @return string
1019
     */
1020
    public function getListingUrl()
1021
    {
1022
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams();
1023
    }
1024
1025
    /**
1026
     * @param array $meeting
1027
     * @return string
1028
     */
1029
    public function endUrl($meeting)
1030
    {
1031
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=end&id='.$meeting['id'];
1032
    }
1033
1034
    /**
1035
     * @param array $meeting
1036
     * @param array $record
1037
     * @return string
1038
     */
1039
    public function addToCalendarUrl($meeting, $record = [])
1040
    {
1041
        $url = isset($record['playbackFormatUrl']) ? $record['playbackFormatUrl'] : '';
1042
1043
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=add_to_calendar&id='.$meeting['id'].'&start='.api_strtotime($meeting['created_at']).'&url='.$url;
1044
    }
1045
1046
    /**
1047
     * @param array $meeting
1048
     * @return string
1049
     */
1050
    public function publishUrl($meeting)
1051
    {
1052
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=publish&id='.$meeting['id'];
1053
    }
1054
1055
    /**
1056
     * @param array $meeting
1057
     * @return string
1058
     */
1059
    public function unPublishUrl($meeting)
1060
    {
1061
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=unpublish&id='.$meeting['id'];
1062
    }
1063
1064
    /**
1065
     * @param array $meeting
1066
     * @return string
1067
     */
1068
    public function deleteRecordUrl($meeting)
1069
    {
1070
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=delete_record&id='.$meeting['id'];
1071
    }
1072
1073
    /**
1074
     * @param array $meeting
1075
     * @return string
1076
     */
1077
    public function copyToRecordToLinkTool($meeting)
1078
    {
1079
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=copy_record_to_link_tool&id='.$meeting['id'];
1080
    }
1081
}
1082