Completed
Push — 1.10.x ( f2fc06...a47b7a )
by
unknown
50:55
created

bbb::deleteRecordUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 2
b 0
f 1
nc 1
nop 1
dl 0
loc 4
rs 10
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
31
    /**
32
     * Constructor (generates a connection to the API and the Chamilo settings
33
     * required for the connection to the video conference server)
34
     * @param string $host
35
     * @param string $salt
36
     */
37
    public function __construct($host = '', $salt = '', $isGlobalConference = false)
38
    {
39
        // Initialize video server settings from global settings
40
        $plugin = BBBPlugin::create();
41
42
        $bbbPlugin = $plugin->get('tool_enable');
43
44
        $bbb_host = !empty($host) ? $host : $plugin->get('host');
45
        $bbb_salt = !empty($salt) ? $salt : $plugin->get('salt');
46
47
        $this->logoutUrl = $this->getListingUrl();
48
        $this->table = Database::get_main_table('plugin_bbb_meeting');
49
        $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...
50
        $this->isGlobalConference = (bool) $isGlobalConference;
51
52
        if ($bbbPlugin === true) {
53
            $userInfo = api_get_user_info();
54
            $this->user_complete_name = $userInfo['complete_name'];
55
            $this->salt = $bbb_salt;
56
            $info = parse_url($bbb_host);
57
            $this->url = $bbb_host.'/bigbluebutton/';
58
            if (isset($info['scheme'])) {
59
                $this->protocol = $info['scheme'].'://';
60
                $this->url = str_replace($this->protocol, '', $this->url);
61
            }
62
63
            // Setting BBB api
64
            define('CONFIG_SECURITY_SALT', $this->salt);
65
            define('CONFIG_SERVER_BASE_URL', $this->url);
66
67
            $this->api = new BigBlueButtonBN();
68
            $this->pluginEnabled = true;
69
        }
70
    }
71
72
    /**
73
     * @return bool
74
     */
75
    public function isGlobalConferenceEnabled()
76
    {
77
        return (bool) $this->enableGlobalConference;
78
    }
79
80
    /**
81
     * @return bool
82
     */
83
    public function isGlobalConference()
84
    {
85
        if ($this->isGlobalConferenceEnabled() === false) {
86
87
            return false;
88
        }
89
90
        return (bool) $this->isGlobalConference;
91
    }
92
93
    /**
94
     * Checks whether a user is teacher in the current course
95
     * @return bool True if the user can be considered a teacher in this course, false otherwise
96
     */
97
    public function isConferenceManager()
98
    {
99
        return api_is_course_admin() || api_is_coach() || api_is_platform_admin();
100
    }
101
102
    /**
103
     * See this file in you BBB to set up default values
104
     * @param   array $params Array of parameters that will be completed if not containing all expected variables
105
106
       /var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties
107
     *
108
       More record information:
109
       http://code.google.com/p/bigbluebutton/wiki/RecordPlaybackSpecification
110
111
       # Default maximum number of users a meeting can have.
112
        # Doesn't get enforced yet but is the default value when the create
113
        # API doesn't pass a value.
114
        defaultMaxUsers=20
115
116
        # Default duration of the meeting in minutes.
117
        # Current default is 0 (meeting doesn't end).
118
        defaultMeetingDuration=0
119
120
        # Remove the meeting from memory when the end API is called.
121
        # This allows 3rd-party apps to recycle the meeting right-away
122
        # instead of waiting for the meeting to expire (see below).
123
        removeMeetingWhenEnded=false
124
125
        # The number of minutes before the system removes the meeting from memory.
126
        defaultMeetingExpireDuration=1
127
128
        # The number of minutes the system waits when a meeting is created and when
129
        # a user joins. If after this period, a user hasn't joined, the meeting is
130
        # removed from memory.
131
        defaultMeetingCreateJoinDuration=5
132
     *
133
     */
134
    public function createMeeting($params)
135
    {
136
        $courseCode = api_get_course_id();
137
        $params['c_id'] = api_get_course_int_id();
138
        $params['session_id'] = api_get_session_id();
139
140
        $params['attendee_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $courseCode;
141
        $attendeePassword =  $params['attendee_pw'];
142
        $params['moderator_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $this->getModMeetingPassword();
143
        $moderatorPassword = $params['moderator_pw'];
144
145
        $params['record'] = api_get_course_setting('big_blue_button_record_and_store', $courseCode) == 1 ? true : false;
146
        $max = api_get_course_setting('big_blue_button_max_students_allowed', $courseCode);
147
        $max =  isset($max) ? $max : -1;
148
149
        $params['status'] = 1;
150
        // Generate a pseudo-global-unique-id to avoid clash of conferences on
151
        // the same BBB server with several Chamilo portals
152
        $params['remote_id'] = uniqid(true, true);
153
        // Each simultaneous conference room needs to have a different
154
        // voice_bridge composed of a 5 digits number, so generating a random one
155
        $params['voice_bridge'] = rand(10000, 99999);
156
157
        if ($this->debug) {
158
            error_log("enter create_meeting ".print_r($params, 1));
159
        }
160
161
        $params['created_at'] = api_get_utc_datetime();
162
        $id = Database::insert($this->table, $params);
163
164
        if ($id) {
165
            if ($this->debug) {
166
                error_log("create_meeting: $id ");
167
            }
168
169
            $meetingName = isset($params['meeting_name']) ? $params['meeting_name'] : api_get_course_id().'-'.api_get_session_id();
170
            $welcomeMessage = isset($params['welcome_msg']) ? $params['welcome_msg'] : null;
171
            $record = isset($params['record']) && $params['record'] ? 'true' : 'false';
172
            $duration = isset($params['duration']) ? intval($params['duration']) : 0;
173
            // This setting currently limits the maximum conference duration,
174
            // to avoid lingering sessions on the video-conference server #6261
175
            $duration = 300;
176
177
            $bbbParams = array(
178
                'meetingId' => $params['remote_id'], 					// REQUIRED
179
                'meetingName' => $meetingName, 	// REQUIRED
180
                'attendeePw' => $attendeePassword, 					// Match this value in getJoinMeetingURL() to join as attendee.
181
                'moderatorPw' => $moderatorPassword, 					// Match this value in getJoinMeetingURL() to join as moderator.
182
                'welcomeMsg' => $welcomeMessage, 					// ''= use default. Change to customize.
183
                'dialNumber' => '', 					// The main number to call into. Optional.
184
                'voiceBridge' => $params['voice_bridge'], 					// PIN to join voice. Required.
185
                'webVoice' => '', 						// Alphanumeric to join voice. Optional.
186
                'logoutUrl' =>  $this->logoutUrl,
187
                'maxParticipants' => $max, 				// Optional. -1 = unlimitted. Not supported in BBB. [number]
188
                'record' => $record, 					// New. 'true' will tell BBB to record the meeting.
189
                'duration' => $duration, 				// Default = 0 which means no set duration in minutes. [number]
190
                //'meta_category' => '', 				// Use to pass additional info to BBB server. See API docs.
191
            );
192
193
            if ($this->debug) {
194
                error_log("create_meeting params: ".print_r($bbbParams,1));
195
            }
196
197
            $status = false;
198
            $meeting = null;
199
200
            while ($status === false) {
201
                $result = $this->api->createMeetingWithXmlResponseArray(
202
                    $bbbParams
203
                );
204
                if (isset($result) && strval($result['returncode']) == 'SUCCESS') {
205
                    if ($this->debug) {
206
                        error_log(
207
                            "create_meeting result: " . print_r($result, 1)
208
                        );
209
                    }
210
                    $meeting = $this->joinMeeting($meetingName, true);
211
212
                    return $meeting;
213
                }
214
            }
215
216
            return $this->logoutUrl;
217
        }
218
    }
219
220
    /**
221
     * Tells whether the given meeting exists and is running
222
     * (using course code as name)
223
     * @param string $meetingName Meeting name (usually the course code)
224
     *
225
     * @return bool True if meeting exists, false otherwise
226
     * @assert ('') === false
227
     * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
228
     */
229
    public function meetingExists($meetingName)
230
    {
231
        if (empty($meetingName)) {
232
233
            return false;
234
        }
235
236
        $courseId = api_get_course_int_id();
237
        $sessionId = api_get_session_id();
238
        $meetingData = Database::select(
239
            '*',
240
            $this->table,
241
            array(
242
                'where' => array(
243
                    'c_id = ? AND session_id = ? AND meeting_name = ? AND status = 1 ' =>
244
                        array($courseId, $sessionId, $meetingName)
245
                )
246
            ),
247
            'first'
248
        );
249
        if ($this->debug) {
250
            error_log("meeting_exists ".print_r($meetingData, 1));
251
        }
252
253
        if (empty($meetingData)) {
254
255
            return false;
256
        } else {
257
            return true;
258
        }
259
    }
260
261
    /**
262
     * Returns a meeting "join" URL
263
     * @param string The name of the meeting (usually the course code)
264
     * @return mixed The URL to join the meeting, or false on error
265
     * @todo implement moderator pass
266
     * @assert ('') === false
267
     * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
268
     */
269
    public function joinMeeting($meetingName, $loop = false)
270
    {
271
        if (empty($meetingName)) {
272
            return false;
273
        }
274
275
        $pass = $this->getUserMeetingPassword();
276
277
        $meetingData = Database::select(
278
            '*',
279
            $this->table,
280
            array('where' => array('meeting_name = ? AND status = 1 ' => $meetingName)),
281
            'first'
282
        );
283
284
        if (empty($meetingData) || !is_array($meetingData)) {
285
            if ($this->debug) {
286
                error_log("meeting does not exist: $meetingName");
287
            }
288
289
            return false;
290
        }
291
292
        $params = array(
293
            'meetingId' => $meetingData['remote_id'],
294
            //  -- REQUIRED - The unique id for the meeting
295
            'password' => $this->getModMeetingPassword()
296
            //  -- REQUIRED - The moderator password for the meeting
297
        );
298
299
        $status = false;
300
        $meetingInfoExists = false;
301
        while ($status === false) {
302
303
            $meetingIsRunningInfo = $this->getMeetingInfo($params);
304 View Code Duplication
            if ($meetingIsRunningInfo === false) {
305
                //checking with the remote_id didn't work, so just in case and
306
                // to provide backwards support, check with the id
307
                $params = array(
308
                    'meetingId' => $meetingData['id'],
309
                    //  -- REQUIRED - The unique id for the meeting
310
                    'password' => $this->getModMeetingPassword()
311
                    //  -- REQUIRED - The moderator password for the meeting
312
                );
313
                $meetingIsRunningInfo = $this->getMeetingInfo($params);
314
            }
315
316
            if ($this->debug) {
317
                error_log(print_r($meetingIsRunningInfo, 1));
318
            }
319
320
            if (strval($meetingIsRunningInfo['returncode']) == 'SUCCESS' &&
321
                isset($meetingIsRunningInfo['meetingName']) &&
322
                !empty($meetingIsRunningInfo['meetingName'])
323
                //strval($meetingIsRunningInfo['running']) == 'true'
324
            ) {
325
                $meetingInfoExists = true;
326
            }
327
328
            if ($this->debug) {
329
                error_log(
330
                    "meeting is running: " . intval($meetingInfoExists)
331
                );
332
            }
333
334
            if ($meetingInfoExists) {
335
                $status = true;
336
            }
337
338
            if ($loop) {
339
                continue;
340
            } else {
341
                break;
342
            }
343
        }
344
345
        if ($meetingInfoExists) {
346
            $joinParams = array(
347
                'meetingId' => $meetingData['remote_id'],	//	-- REQUIRED - A unique id for the meeting
348
                'username' => $this->user_complete_name,	//-- REQUIRED - The name that will display for the user in the meeting
349
                'password' => $pass,			//-- REQUIRED - The attendee or moderator password, depending on what's passed here
350
                //'createTime' => api_get_utc_datetime(),			//-- OPTIONAL - string. Leave blank ('') unless you set this correctly.
351
                'userID' => api_get_user_id(),				//-- OPTIONAL - string
352
                'webVoiceConf' => ''	//	-- OPTIONAL - string
353
            );
354
            $url = $this->api->getJoinMeetingURL($joinParams);
355
            $url = $this->protocol.$url;
356
        } else {
357
            $url = $this->logoutUrl;
358
        }
359
        if ($this->debug) {
360
            error_log("return url :" . $url);
361
        }
362
363
        return $url;
364
    }
365
366
    /**
367
     * Get information about the given meeting
368
     * @param array ...?
369
     * @return mixed Array of information on success, false on error
370
     * @assert (array()) === false
371
     */
372
    public function getMeetingInfo($params)
373
    {
374
        try {
375
            $result = $this->api->getMeetingInfoWithXmlResponseArray($params);
376
            if ($result == null) {
377
                if ($this->debug) {
378
                    error_log("Failed to get any response. Maybe we can't contact the BBB server.");
379
                }
380
            } else {
381
                return $result;
382
            }
383
        } catch (Exception $e) {
384
            if ($this->debug) {
385
                error_log('Caught exception: ', $e->getMessage(), "\n");
386
            }
387
        }
388
389
        return false;
390
    }
391
392
    /**
393
     * Gets all the course meetings saved in the plugin_bbb_meeting table
394
     * @return array Array of current open meeting rooms
395
     */
396
    public function getMeetings()
397
    {
398
        $pass = $this->getUserMeetingPassword();
399
        $meetingList = Database::select(
400
            '*',
401
            $this->table,
402
            array(
403
                'where' => array(
404
                    'c_id = ? AND session_id = ? ' => array(
405
                        api_get_course_int_id(),
406
                        api_get_session_id(),
407
                    ),
408
                ),
409
            )
410
        );
411
        $isGlobal = $this->isGlobalConference();
412
        $newMeetingList = array();
413
        $item = array();
414
        foreach ($meetingList as $meetingDB) {
415
            $meetingBBB = $this->getMeetingInfo(['meetingId' => $meetingDB['remote_id'], 'password' => $pass]);
416 View Code Duplication
            if ($meetingBBB === false) {
417
                //checking with the remote_id didn't work, so just in case and
418
                // to provide backwards support, check with the id
419
                $params = array(
420
                    'meetingId' => $meetingDB['id'],
421
                    //  -- REQUIRED - The unique id for the meeting
422
                    'password' => $pass
423
                    //  -- REQUIRED - The moderator password for the meeting
424
                );
425
                $meetingBBB = $this->getMeetingInfo($params);
426
            }
427
428
            if ($meetingDB['visibility'] == 0 && $this->isConferenceManager() === false) {
429
                continue;
430
            }
431
            $meetingBBB['end_url'] = $this->endUrl($meetingDB);
432
433
            if ((string)$meetingBBB['returncode'] == 'FAILED') {
434
                if ($meetingDB['status'] == 1 && $this->isConferenceManager()) {
435
                    $this->endMeeting($meetingDB['id']);
436
                }
437
            } else {
438
                $meetingBBB['add_to_calendar_url'] = $this->addToCalendarUrl($meetingDB);
439
            }
440
441
            $recordArray = array();
442
            $actionLinksArray = array();
443
444
            if ($meetingDB['record'] == 1) {
445
                // backwards compatibility (when there was no remote ID)
446
                $mId = $meetingDB['remote_id'];
447
                if (empty($mId)) {
448
                    $mId = $meetingDB['id'];
449
                }
450
                if (empty($mId)) {
451
                    // if the id is still empty (should *never* occur as 'id' is
452
                    // the table's primary key), skip this conference
453
                    continue;
454
                }
455
                $recordingParams = array(
456
                    'meetingId' => $mId, //-- OPTIONAL - comma separate if multiple ids
457
                );
458
459
                //To see the recording list in your BBB server do: bbb-record --list
460
                $records = $this->api->getRecordingsWithXmlResponseArray($recordingParams);
461
                if (!empty($records)) {
462
                    $count = 1;
463
                    if (isset($records['message']) && !empty($records['message'])) {
464
                        if ($records['messageKey'] == 'noRecordings') {
465
                            $recordArray[] = get_lang('NoRecording');
466
                            if ($meetingDB['visibility'] == 0) {
467
                                $actionLinksArray[] = Display::url(
468
                                    Display::return_icon(
469
                                        'invisible.png',
470
                                        get_lang('MakeVisible'),
471
                                        array(),
472
                                        ICON_SIZE_MEDIUM
473
                                    ),
474
                                    $this->publishUrl($meetingDB)
475
                                );
476
                            } else {
477
                                $actionLinksArray[] = Display::url(
478
                                    Display::return_icon(
479
                                        'visible.png',
480
                                        get_lang('MakeInvisible'),
481
                                        array(),
482
                                        ICON_SIZE_MEDIUM
483
                                    ),
484
                                    $this->unPublishUrl($meetingDB)
485
                                );
486
                            }
487
                        }
488
                    } else {
489
                        foreach ($records as $record) {
490
                            //if you get several recordings here and you used a
491
                            // previous version of Chamilo, you might want to
492
                            // only keep the last result for each chamilo conf
493
                            // (see show_links after the end of this loop)
494
                            if (is_array($record) && isset($record['recordId'])) {
495
                                $url = Display::url(
496
                                    get_lang('ViewRecord')." [~".$record['playbackFormatLength']."']",
497
                                    $record['playbackFormatUrl'],
498
                                    array('target' => '_blank')
499
                                );
500
                                $actionLinks = '';
501
                                if ($this->isConferenceManager()) {
502
                                    if ($isGlobal === false) {
503
                                        $actionLinks .= Display::url(
504
                                            Display::return_icon(
505
                                                'link.gif',
506
                                                get_lang('CopyToLinkTool')
507
                                            ),
508
                                            $this->copyToRecordToLinkTool($meetingDB)
509
                                        );
510
                                        $actionLinks .= Display::url(
511
                                            Display::return_icon(
512
                                                'agenda.png',
513
                                                get_lang('AddToCalendar')
514
                                            ),
515
                                            $this->addToCalendarUrl($meetingDB, $record)
516
                                        );
517
                                    }
518
                                    $actionLinks .= Display::url(
519
                                        Display::return_icon(
520
                                            'delete.png',
521
                                            get_lang('Delete')
522
                                        ),
523
                                        $this->deleteRecordUrl($meetingDB)
524
                                    );
525
526 View Code Duplication
                                    if ($meetingDB['visibility'] == 0) {
527
                                        $actionLinks .= Display::url(
528
                                            Display::return_icon(
529
                                                'invisible.png',
530
                                                get_lang('MakeVisible'),
531
                                                array(),
532
                                                ICON_SIZE_MEDIUM
533
                                            ),
534
                                            $this->publishUrl($meetingDB)
535
                                        );
536
                                    } else {
537
                                        $actionLinks .= Display::url(
538
                                            Display::return_icon(
539
                                                'visible.png',
540
                                                get_lang('MakeInvisible'),
541
                                                array(),
542
                                                ICON_SIZE_MEDIUM
543
                                            ),
544
                                            $this->unPublishUrl($meetingDB)
545
                                        );
546
                                    }
547
                                }
548
                                $count++;
549
                                $recordArray[] = $url;
550
                                $actionLinksArray[] = $actionLinks;
551
                            } 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...
552
                                /*if (is_array($record) && isset($record['recordID']) && isset($record['playbacks'])) {
553
554
                                    //Fix the bbb timestamp
555
                                    //$record['startTime'] = substr($record['startTime'], 0, strlen($record['startTime']) -3);
556
                                    //$record['endTime']   = substr($record['endTime'], 0, strlen($record['endTime']) -3);
557
                                    //.' - '.api_convert_and_format_date($record['startTime']).' - '.api_convert_and_format_date($record['endTime'])
558
                                    foreach($record['playbacks'] as $item) {
559
                                        $url = Display::url(get_lang('ViewRecord'), $item['url'], array('target' => '_blank'));
560
                                        //$url .= Display::url(get_lang('DeleteRecord'), api_get_self().'?action=delete_record&'.$record['recordID']);
561
                                        if ($this->isConferenceManager()) {
562
                                            $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']);
563
                                            $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']);
564
                                            $url .= Display::url(Display::return_icon('delete.png',get_lang('Delete')), api_get_self().'?action=delete_record&id='.$record['recordID']);
565
                                        }
566
                                        //$url .= api_get_self().'?action=publish&id='.$record['recordID'];
567
                                        $count++;
568
                                        $recordArray[] = $url;
569
                                    }
570
                                }*/
571
                            }
572
                        }
573
                    }
574
                } else {
575
                    $actionLinks = '';
576 View Code Duplication
                    if ($this->isConferenceManager()) {
577
                        if ($meetingDB['visibility'] == 0) {
578
                            $actionLinks .= Display::url(
579
                                Display::return_icon(
580
                                    'invisible.png',
581
                                    get_lang('MakeVisible'),
582
                                    array(),
583
                                    ICON_SIZE_MEDIUM
584
                                ),
585
                                $this->publishUrl($meetingDB)
586
                            );
587
                        } else {
588
                            $actionLinks .= Display::url(
589
                                Display::return_icon(
590
                                    'visible.png',
591
                                    get_lang('MakeInvisible'),
592
                                    array(),
593
                                    ICON_SIZE_MEDIUM
594
                                ),
595
                                $this->unPublishUrl($meetingDB)
596
                            );
597
                        }
598
                    }
599
                    $actionLinksArray[] = $actionLinks;
600
                    $item['action_links'] = implode('<br />', $actionLinksArray);
601
                }
602
                //var_dump($recordArray);
603
                $item['show_links']  = implode('<br />', $recordArray);
604
                $item['action_links'] = implode('<br />', $actionLinksArray);
605
            }
606
607
            $item['created_at'] = api_convert_and_format_date($meetingDB['created_at']);
608
            //created_at
609
            $meetingDB['created_at'] = $item['created_at']; //avoid overwrite in array_merge() below
610
611
            $item['publish_url'] = $this->publishUrl($meetingDB);
612
            $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...
613
614
            if ($meetingDB['status'] == 1) {
615
                $joinParams = array(
616
                    'meetingId' => $meetingDB['remote_id'],		//-- REQUIRED - A unique id for the meeting
617
                    'username' => $this->user_complete_name,	//-- REQUIRED - The name that will display for the user in the meeting
618
                    'password' => $pass,			//-- REQUIRED - The attendee or moderator password, depending on what's passed here
619
                    'createTime' => '',			//-- OPTIONAL - string. Leave blank ('') unless you set this correctly.
620
                    'userID' => '',			//	-- OPTIONAL - string
621
                    'webVoiceConf' => ''	//	-- OPTIONAL - string
622
                );
623
                $item['go_url'] = $this->protocol.$this->api->getJoinMeetingURL($joinParams);
624
            }
625
            $item = array_merge($item, $meetingDB, $meetingBBB);
626
            $newMeetingList[] = $item;
627
        }
628
629
        return $newMeetingList;
630
    }
631
632
    /**
633
     * Function disabled
634
     */
635 View Code Duplication
    public function publishMeeting($id)
636
    {
637
        //return BigBlueButtonBN::setPublishRecordings($id, 'true', $this->url, $this->salt);
638
        if (empty($id)) {
639
640
            return false;
641
        }
642
        $id = intval($id);
643
        Database::update($this->table, array('visibility' => 1), array('id = ? ' => $id));
644
645
        return true;
646
    }
647
648
    /**
649
     * Function disabled
650
     */
651 View Code Duplication
    public function unpublishMeeting($id)
652
    {
653
        //return BigBlueButtonBN::setPublishRecordings($id, 'false', $this->url, $this->salt);
654
        if (empty($id)) {
655
656
            return false;
657
        }
658
        $id = intval($id);
659
        Database::update($this->table, array('visibility' => 0), array('id = ?' => $id));
660
661
        return true;
662
    }
663
664
    /**
665
     * Closes a meeting (usually when the user click on the close button from
666
     * the conferences listing.
667
     * @param string The internal ID of the meeting (id field for this meeting)
668
     * @return void
669
     * @assert (0) === false
670
     */
671
    public function endMeeting($id)
672
    {
673
        if (empty($id)) {
674
675
            return false;
676
        }
677
        $meetingData = Database::select('*', $this->table, array('where' => array('id = ?' => array($id))), 'first');
678
        $pass = $this->getUserMeetingPassword();
679
680
        $endParams = array(
681
            'meetingId' => $meetingData['remote_id'],   // REQUIRED - We have to know which meeting to end.
682
            'password' => $pass,        // REQUIRED - Must match moderator pass for meeting.
683
        );
684
        $this->api->endMeetingWithXmlResponseArray($endParams);
685
        Database::update(
686
            $this->table,
687
            array('status' => 0, 'closed_at' => api_get_utc_datetime()),
688
            array('id = ? ' => $id)
689
        );
690
    }
691
692
    /**
693
     * Gets the password for a specific meeting for the current user
694
     * @return string A moderator password if user is teacher, or the course code otherwise
695
     */
696
    public function getUserMeetingPassword()
697
    {
698
        if ($this->isConferenceManager()) {
699
700
            return $this->getModMeetingPassword();
701
        } else {
702
703
            if ($this->isGlobalConference()) {
704
705
                return 'url_'.api_get_current_access_url_id();
706
            }
707
708
            return api_get_course_id();
709
        }
710
    }
711
712
    /**
713
     * Generated a moderator password for the meeting
714
     * @return string A password for the moderation of the videoconference
715
     */
716
    public function getModMeetingPassword()
717
    {
718
        if ($this->isGlobalConference()) {
719
720
            return 'url_'.api_get_current_access_url_id().'_mod';
721
        }
722
723
        return api_get_course_id().'mod';
724
    }
725
726
    /**
727
     * Get users online in the current course room
728
     * @return int The number of users currently connected to the videoconference
729
     * @assert () > -1
730
     */
731
    public function getUsersOnlineInCurrentRoom()
732
    {
733
        $courseId = api_get_course_int_id();
734
        $sessionId = api_get_session_id();
735
        $meetingData = Database::select(
736
            '*',
737
            $this->table,
738
            array('where' => array('c_id = ? AND session_id = ? AND status = 1 ' => array($courseId, $sessionId))),
739
            'first'
740
        );
741
        if (empty($meetingData)) {
742
            return 0;
743
        }
744
        $pass = $this->getModMeetingPassword();
745
        $info = $this->getMeetingInfo(array('meetingId' => $meetingData['remote_id'], 'password' => $pass));
746 View Code Duplication
        if ($info === false) {
747
            //checking with the remote_id didn't work, so just in case and
748
            // to provide backwards support, check with the id
749
            $params = array(
750
                'meetingId' => $meetingData['id'],
751
                //  -- REQUIRED - The unique id for the meeting
752
                'password' => $pass
753
                //  -- REQUIRED - The moderator password for the meeting
754
            );
755
            $info = $this->getMeetingInfo($params);
756
        }
757
758
        if (!empty($info) && isset($info['participantCount'])) {
759
            return $info['participantCount'];
760
761
        }
762
        return 0;
763
    }
764
765
    /**
766
     * Deletes a previous recording of a meeting
767
     * @param int integral ID of the recording
768
     * @return array ?
769
     * @assert () === false
770
     * @todo Also delete links and agenda items created from this recording
771
     */
772
    public function deleteRecord($id)
773
    {
774
        if (empty($id)) {
775
            return false;
776
        }
777
778
        $meetingData = Database::select(
779
            '*',
780
            $this->table,
781
            array('where' => array('id = ?' => array($id))),
782
            'first'
783
        );
784
785
        $recordingParams = array(
786
            /*
787
             * NOTE: Set the recordId below to a valid id after you have
788
             * created a recorded meeting, and received a real recordID
789
             * back from your BBB server using the
790
             * getRecordingsWithXmlResponseArray method.
791
             */
792
793
            // REQUIRED - We have to know which recording:
794
            'recordId' => $meetingData['remote_id'],
795
        );
796
797
        $result = $this->api->deleteRecordingsWithXmlResponseArray($recordingParams);
798
799
        if (!empty($result) && isset($result['deleted']) && $result['deleted'] == 'true') {
800
            Database::delete(
801
                $this->table,
802
                array('id = ?' => array($id))
803
            );
804
        }
805
806
        return $result;
807
    }
808
809
    /**
810
     * Creates a link in the links tool from the given videoconference recording
811
     * @param int ID of the item in the plugin_bbb_meeting table
812
     * @param string Hash identifying the recording, as provided by the API
813
     * @return mixed ID of the newly created link, or false on error
814
     * @assert (null, null) === false
815
     * @assert (1, null) === false
816
     * @assert (null, 'abcdefabcdefabcdefabcdef') === false
817
     */
818
    public function copyRecordToLinkTool($id)
819
    {
820
        if (empty($id)) {
821
            return false;
822
        }
823
        //$records =  BigBlueButtonBN::getRecordingsUrl($id);
824
        $meetingData = Database::select('*', $this->table, array('where' => array('id = ?' => array($id))), 'first');
825
826
        $records = $this->api->getRecordingsWithXmlResponseArray(array('meetingId' => $meetingData['remote_id']));
827
828
        if (!empty($records)) {
829
            if (isset($records['message']) && !empty($records['message'])) {
830
                if ($records['messageKey'] == 'noRecordings') {
831
                    $recordArray[] = get_lang('NoRecording');
832
                } 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...
833
                    //$recordArray[] = $records['message'];
834
                }
835
                return false;
836
            } else {
837
                $record = $records[0];
838
                if (is_array($record) && isset($record['recordId'])) {
839
                    $url = $record['playbackFormatUrl'];
840
                    $link = new Link();
0 ignored issues
show
Bug introduced by
The call to Link::__construct() misses some required arguments starting with $id.
Loading history...
841
                    $params['url'] = $url;
842
                    $params['title'] = $meetingData['meeting_name'];
843
                    $id = $link->save($params);
844
                    return $id;
845
                }
846
            }
847
        }
848
849
        return false;
850
    }
851
852
    /**
853
     * Checks if the videoconference server is running.
854
     * Function currently disabled (always returns 1)
855
     * @return bool True if server is running, false otherwise
856
     * @assert () === false
857
     */
858
    public function isServerRunning()
859
    {
860
        return true;
861
        //return BigBlueButtonBN::isServerRunning($this->protocol.$this->url);
862
    }
863
864
    /**
865
     * Get active session in the all platform
866
     */
867
    public function getActiveSessionsCount()
868
    {
869
        $meetingList = Database::select(
870
            'count(id) as count',
871
            $this->table,
872
            array('where' => array('status = ?' => array(1))),
873
            'first'
874
        );
875
876
        return $meetingList['count'];
877
    }
878
879
    /**
880
     * @param string $url
881
     */
882
    public function redirectToBBB($url)
883
    {
884
        if (file_exists(__DIR__ . '/../config.vm.php')) {
885
            // Using VM
886
            echo Display::url(get_lang('ClickToContinue'), $url);
887
            exit;
888
        } else {
889
            // Classic
890
            header("Location: $url");
891
            exit;
892
        }
893
894
        // js
895
        /*echo '<script>';
896
        echo 'window.location = "'.$url.'"';
897
        echo '</script>';
898
        exit;*/
899
    }
900
901
    /**
902
     * @return string
903
     */
904
    public function getUrlParams()
905
    {
906
        $courseInfo = api_get_course_info();
907
908
        if (empty($courseInfo)) {
909
910
            if ($this->isGlobalConference()) {
911
                return 'global=1';
912
            }
913
914
            return '';
915
        }
916
917
        return api_get_cidreq();
918
    }
919
920
    /**
921
     * @return string
922
     */
923
    public function getCurrentVideoConferenceName()
924
    {
925
        if ($this->isGlobalConference()) {
926
            return 'url_'.api_get_current_access_url_id();
927
        }
928
929
        return api_get_course_id().'-'.api_get_session_id();
930
    }
931
932
    /**
933
     * @return string
934
     */
935
    public function getConferenceUrl()
936
    {
937
        return api_get_path(WEB_PLUGIN_PATH).'bbb/start.php?launch=1&'.$this->getUrlParams();
938
    }
939
940
    /**
941
     * @return string
942
     */
943
    public function getListingUrl()
944
    {
945
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams();
946
    }
947
948
    /**
949
     * @param array $meeting
950
     * @return string
951
     */
952
    public function endUrl($meeting)
953
    {
954
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=end&id='.$meeting['id'];
955
    }
956
957
    /**
958
     * @param array $meeting
959
     * @param array $record
960
     * @return string
961
     */
962
    public function addToCalendarUrl($meeting, $record = [])
963
    {
964
        $url = isset($record['playbackFormatUrl']) ? $record['playbackFormatUrl'] : '';
965
966
        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;
967
    }
968
969
    /**
970
     * @param array $meeting
971
     * @return string
972
     */
973
    public function publishUrl($meeting)
974
    {
975
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=publish&id='.$meeting['id'];
976
    }
977
978
    /**
979
     * @param array $meeting
980
     * @return string
981
     */
982
    public function unPublishUrl($meeting)
983
    {
984
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=unpublish&id='.$meeting['id'];
985
    }
986
987
    /**
988
     * @param array $meeting
989
     * @return string
990
     */
991
    public function deleteRecordUrl($meeting)
992
    {
993
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=delete_record&id='.$meeting['id'];
994
    }
995
996
    /**
997
     * @param array $meeting
998
     * @return string
999
     */
1000
    public function copyToRecordToLinkTool($meeting)
1001
    {
1002
        return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=copy_record_to_link_tool&id='.$meeting['id'];
1003
    }
1004
}
1005