Completed
Pull Request — master (#242)
by
unknown
02:06
created

locallib.php ➔ bigbluebuttonbn_settings_disablepublicchat()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17
/**
18
 * Internal library of functions for module BigBlueButtonBN.
19
 *
20
 * @package   mod_bigbluebuttonbn
21
 * @copyright 2010 onwards, Blindside Networks Inc
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
24
 * @author    Fred Dixon  (ffdixon [at] blindsidenetworks [dt] com)
25
 */
26
27
use mod_bigbluebuttonbn\locallib;
28
use mod_bigbluebuttonbn\plugin;
29
use mod_bigbluebuttonbn\task;
30
31
defined('MOODLE_INTERNAL') || die;
32
33
global $CFG;
34
35
require_once(__DIR__ . '/lib.php');
36
37
/** @var BIGBLUEBUTTONBN_UPDATE_CACHE boolean set to true indicates that cache has to be updated */
38
const BIGBLUEBUTTONBN_UPDATE_CACHE = true;
39
/** @var BIGBLUEBUTTONBN_TYPE_ALL integer set to 0 defines an instance type that inclueds room and recordings */
40
const BIGBLUEBUTTONBN_TYPE_ALL = 0;
41
/** @var BIGBLUEBUTTONBN_TYPE_ROOM_ONLY integer set to 1 defines an instance type that inclueds only room */
42
const BIGBLUEBUTTONBN_TYPE_ROOM_ONLY = 1;
43
/** @var BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY integer set to 2 defines an instance type that inclueds only recordings */
44
const BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY = 2;
45
/** @var BIGBLUEBUTTONBN_ROLE_VIEWER string defines the bigbluebutton viewer role */
46
const BIGBLUEBUTTONBN_ROLE_VIEWER = 'viewer';
47
/** @var BIGBLUEBUTTONBN_ROLE_MODERATOR string defines the bigbluebutton moderator role */
48
const BIGBLUEBUTTONBN_ROLE_MODERATOR = 'moderator';
49
/** @var BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED string defines the bigbluebuttonbn activity_viewed event */
50
const BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED = 'activity_viewed';
51
/** @var BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED string defines the bigbluebuttonbn activity_management_viewed event */
52
const BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED = 'activity_management_viewed';
53
/** @var BIGBLUEBUTTON_EVENT_LIVE_SESSION string defines the bigbluebuttonbn live_session event */
54
const BIGBLUEBUTTON_EVENT_LIVE_SESSION = 'live_session';
55
/** @var BIGBLUEBUTTON_EVENT_MEETING_CREATED string defines the bigbluebuttonbn meeting_created event */
56
const BIGBLUEBUTTON_EVENT_MEETING_CREATED = 'meeting_created';
57
/** @var BIGBLUEBUTTON_EVENT_MEETING_ENDED string defines the bigbluebuttonbn meeting_ended event */
58
const BIGBLUEBUTTON_EVENT_MEETING_ENDED = 'meeting_ended';
59
/** @var BIGBLUEBUTTON_EVENT_MEETING_JOINED string defines the bigbluebuttonbn meeting_joined event */
60
const BIGBLUEBUTTON_EVENT_MEETING_JOINED = 'meeting_joined';
61
/** @var BIGBLUEBUTTON_EVENT_MEETING_LEFT string defines the bigbluebuttonbn meeting_left event */
62
const BIGBLUEBUTTON_EVENT_MEETING_LEFT = 'meeting_left';
63
/** @var BIGBLUEBUTTON_EVENT_RECORDING_DELETED string defines the bigbluebuttonbn recording_deleted event */
64
const BIGBLUEBUTTON_EVENT_RECORDING_DELETED = 'recording_deleted';
65
/** @var BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED string defines the bigbluebuttonbn recording_imported event */
66
const BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED = 'recording_imported';
67
/** @var BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED string defines the bigbluebuttonbn recording_protected event */
68
const BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED = 'recording_protected';
69
/** @var BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED string defines the bigbluebuttonbn recording_published event */
70
const BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED = 'recording_published';
71
/** @var BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED string defines the bigbluebuttonbn recording_unprotected event */
72
const BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED = 'recording_unprotected';
73
/** @var BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED string defines the bigbluebuttonbn recording_unpublished event */
74
const BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED = 'recording_unpublished';
75
/** @var BIGBLUEBUTTON_EVENT_RECORDING_EDITED string defines the bigbluebuttonbn recording_edited event */
76
const BIGBLUEBUTTON_EVENT_RECORDING_EDITED = 'recording_edited';
77
/** @var BIGBLUEBUTTON_EVENT_RECORDING_VIEWED string defines the bigbluebuttonbn recording_viewed event */
78
const BIGBLUEBUTTON_EVENT_RECORDING_VIEWED = 'recording_viewed';
79
/** @var BIGBLUEBUTTON_EVENT_MEETING_START string defines the bigbluebuttonbn meeting_start event */
80
const BIGBLUEBUTTON_EVENT_MEETING_START = 'meeting_start';
81
/** @var BIGBLUEBUTTON_CLIENTTYPE_FLASH integer that defines the bigbluebuttonbn default web client based on Adobe FLASH */
82
const BIGBLUEBUTTON_CLIENTTYPE_FLASH = 0;
83
/** @var BIGBLUEBUTTON_CLIENTTYPE_HTML5 integer that defines the bigbluebuttonbn default web client based on HTML5 */
84
const BIGBLUEBUTTON_CLIENTTYPE_HTML5 = 1;
85
/** @var BIGBLUEBUTTON_ORIGIN_BASE integer set to 0 defines that the user acceded the session from activity page */
86
const BIGBLUEBUTTON_ORIGIN_BASE = 0;
87
/** @var BIGBLUEBUTTON_ORIGIN_TIMELINE integer set to 1 defines that the user acceded the session from Timeline */
88
const BIGBLUEBUTTON_ORIGIN_TIMELINE = 1;
89
/** @var BIGBLUEBUTTON_ORIGIN_INDEX integer set to 2 defines that the user acceded the session from Index */
90
const BIGBLUEBUTTON_ORIGIN_INDEX = 2;
91
92
/**
93
 * Builds and retunrs a url for joining a bigbluebutton meeting.
94
 *
95
 * @param string $meetingid
96
 * @param string $username
97
 * @param string $pw
98
 * @param string $logouturl
99
 * @param string $configtoken
100
 * @param string $userid
101
 * @param string $clienttype
102
 *
103
 * @return string
104
 */
105
function bigbluebuttonbn_get_join_url(
106
    $meetingid,
107
    $username,
108
    $pw,
109
    $logouturl,
110
    $configtoken = null,
111
    $userid = null,
112
    $clienttype = BIGBLUEBUTTON_CLIENTTYPE_FLASH
113
) {
114
    $data = ['meetingID' => $meetingid,
115
        'fullName' => $username,
116
        'password' => $pw,
117
        'logoutURL' => $logouturl,
118
    ];
119
    // Choose between Adobe Flash or HTML5 Client.
120
    if ($clienttype == BIGBLUEBUTTON_CLIENTTYPE_HTML5) {
121
        $data['joinViaHtml5'] = 'true';
122
    }
123
    if (!is_null($configtoken)) {
124
        $data['configToken'] = $configtoken;
125
    }
126
    if (!is_null($userid)) {
127
        $data['userID'] = $userid;
128
    }
129
    return \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('join', $data);
130
}
131
132
/**
133
 * Creates a bigbluebutton meeting and returns the response in an array.
134
 *
135
 * @param array  $data
136
 * @param array  $metadata
137
 * @param string $pname
138
 * @param string $purl
139
 *
140
 * @return array
141
 */
142
function bigbluebuttonbn_get_create_meeting_array($data, $metadata = array(), $pname = null, $purl = null) {
143
    $createmeetingurl = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('create', $data, $metadata);
144
    $method = 'GET';
145
    $data = null;
146
    if (!is_null($pname) && !is_null($purl)) {
147
        $method = 'POST';
148
        $data = "<?xml version='1.0' encoding='UTF-8'?><modules><module name='presentation'><document url='" .
149
            $purl . "' /></module></modules>";
150
    }
151
    $xml = bigbluebuttonbn_wrap_xml_load_file($createmeetingurl, $method, $data);
152
    if ($xml) {
153
        $response = array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
154
        if ($xml->meetingID) {
155
            $response += array('meetingID' => $xml->meetingID, 'attendeePW' => $xml->attendeePW,
156
                'moderatorPW' => $xml->moderatorPW, 'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded);
157
        }
158
        return $response;
159
    }
160
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
161
}
162
163
/**
164
 * Fetch meeting info and wrap response in array.
165
 *
166
 * @param string $meetingid
167
 *
168
 * @return array
169
 */
170
function bigbluebuttonbn_get_meeting_info_array($meetingid) {
171
    $xml = bigbluebuttonbn_wrap_xml_load_file(
172
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
173
    );
174
    if ($xml && $xml->returncode == 'SUCCESS' && empty($xml->messageKey)) {
175
        // Meeting info was returned.
176
        return array('returncode' => $xml->returncode,
177
            'meetingID' => $xml->meetingID,
178
            'moderatorPW' => $xml->moderatorPW,
179
            'attendeePW' => $xml->attendeePW,
180
            'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded,
181
            'running' => $xml->running,
182
            'recording' => $xml->recording,
183
            'startTime' => $xml->startTime,
184
            'endTime' => $xml->endTime,
185
            'participantCount' => $xml->participantCount,
186
            'moderatorCount' => $xml->moderatorCount,
187
            'attendees' => $xml->attendees,
188
            'metadata' => $xml->metadata,
189
        );
190
    }
191
    if ($xml) {
192
        // Either failure or success without meeting info.
193
        return (array) $xml;
194
    }
195
    // If the server is unreachable, then prompts the user of the necessary action.
196
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
197
}
198
199
/**
200
 * Helper function to retrieve recordings from a BigBlueButton server.
201
 *
202
 * @param string|array $meetingids   list of meetingIDs "mid1,mid2,mid3" or array("mid1","mid2","mid3")
203
 * @param string|array $recordingids list of $recordingids "rid1,rid2,rid3" or array("rid1","rid2","rid3") for filtering
204
 *
205
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
206
 */
207
function bigbluebuttonbn_get_recordings_array($meetingids, $recordingids = []) {
208
    $meetingidsarray = $meetingids;
209
    if (!is_array($meetingids)) {
210
        $meetingidsarray = explode(',', $meetingids);
211
    }
212
    // If $meetingidsarray is empty there is no need to go further.
213
    if (empty($meetingidsarray)) {
214
        return array();
215
    }
216
    $recordings = bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray);
0 ignored issues
show
Bug introduced by
It seems like $meetingidsarray defined by $meetingids on line 208 can also be of type string; however, bigbluebuttonbn_get_recordings_array_fetch() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
217
    // Sort recordings.
218
    uasort($recordings, 'bigbluebuttonbn_recording_build_sorter');
219
    // Filter recordings based on recordingIDs.
220
    $recordingidsarray = $recordingids;
221
    if (!is_array($recordingids)) {
222
        $recordingidsarray = explode(',', $recordingids);
223
    }
224
    if (empty($recordingidsarray)) {
225
        // No recording ids, no need to filter.
226
        return $recordings;
227
    }
228
    return bigbluebuttonbn_get_recordings_array_filter($recordingidsarray, $recordings);
0 ignored issues
show
Bug introduced by
It seems like $recordingidsarray defined by $recordingids on line 220 can also be of type string; however, bigbluebuttonbn_get_recordings_array_filter() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
229
}
230
231
/**
232
 * Helper function to fetch recordings from a BigBlueButton server.
233
 *
234
 * @param array $meetingidsarray array with meeting ids in the form array("mid1","mid2","mid3")
235
 *
236
 * @return array (associative) with recordings indexed by recordID, each recording is a non sequential associative array
237
 */
238
function bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray) {
239
    if ((defined('PHPUNIT_TEST') && PHPUNIT_TEST)
240
            || defined('BEHAT_SITE_RUNNING')
241
            || defined('BEHAT_TEST')
242
            || defined('BEHAT_UTIL')) {
243
        // Just return the fake recording.
244
        global $CFG;
245
        require_once($CFG->libdir . '/testing/generator/lib.php');
246
        require_once(__DIR__ . '/tests/generator/lib.php');
247
        return mod_bigbluebuttonbn_generator::bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray);
248
    }
249
    $recordings = array();
250
    // Execute a paginated getRecordings request.
251
    $pagecount = 25;
252
    $pages = floor(count($meetingidsarray) / $pagecount) + 1;
253
    if (count($meetingidsarray) > 0 && count($meetingidsarray) % $pagecount == 0) {
254
        $pages--;
255
    }
256
    for ($page = 1; $page <= $pages; ++$page) {
257
        $mids = array_slice($meetingidsarray, ($page - 1) * $pagecount, $pagecount);
258
        $recordings += bigbluebuttonbn_get_recordings_array_fetch_page($mids);
259
    }
260
    return $recordings;
261
}
262
263
/**
264
 * Helper function to fetch one page of upto 25 recordings from a BigBlueButton server.
265
 *
266
 * @param array  $mids
267
 *
268
 * @return array
269
 */
270
function bigbluebuttonbn_get_recordings_array_fetch_page($mids) {
271
    $recordings = array();
272
    // Do getRecordings is executed using a method GET (supported by all versions of BBB).
273
    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings', ['meetingID' => implode(',', $mids)]);
274
    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
275
    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
276
        // If there were meetings already created.
277
        foreach ($xml->recordings->recording as $recordingxml) {
278
            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
279
            $recordings[$recording['recordID']] = $recording;
280
281
            // Check if there is childs.
282
            if (isset($recordingxml->breakoutRooms->breakoutRoom)) {
283
                foreach ($recordingxml->breakoutRooms->breakoutRoom as $breakoutroom) {
284
                    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url(
285
                        'getRecordings',
286
                        ['recordID' => implode(',', (array) $breakoutroom)]
287
                    );
288
                    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
289
                    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
290
                        // If there were meetings already created.
291
                        foreach ($xml->recordings->recording as $recordingxml) {
292
                            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
293
                            $recordings[$recording['recordID']] = $recording;
294
                        }
295
                    }
296
                }
297
            }
298
        }
299
    }
300
    return $recordings;
301
}
302
303
/**
304
 * Helper function to remove a set of recordings from an array.
305
 *
306
 * @param array  $rids
307
 * @param array  $recordings
308
 *
309
 * @return array
310
 */
311
function bigbluebuttonbn_get_recordings_array_filter($rids, &$recordings) {
312
    foreach ($recordings as $key => $recording) {
313
        if (!in_array($recording['recordID'], $rids)) {
314
            unset($recordings[$key]);
315
        }
316
    }
317
    return $recordings;
318
}
319
320
/**
321
 * Helper function to retrieve imported recordings from the Moodle database.
322
 * The references are stored as events in bigbluebuttonbn_logs.
323
 *
324
 * @param string $courseid
325
 * @param string $bigbluebuttonbnid
326
 * @param bool   $subset
327
 *
328
 * @return associative array with imported recordings indexed by recordID, each recording
329
 * is a non sequential associative array that corresponds to the actual recording in BBB
330
 */
331
function bigbluebuttonbn_get_recordings_imported_array($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
332
    global $DB;
333
    $select = bigbluebuttonbn_get_recordings_imported_sql_select($courseid, $bigbluebuttonbnid, $subset);
334
    $recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select);
335
    $recordsimportedarray = array();
336
    foreach ($recordsimported as $recordimported) {
337
        $meta = json_decode($recordimported->meta, true);
338
        $recording = $meta['recording'];
339
        // Override imported flag with actual ID.
340
        $recording['imported'] = $recordimported->id;
341
        if (isset($recordimported->protected)) {
342
            $recording['protected'] = (string) $recordimported->protected;
343
        }
344
        $recordsimportedarray[$recording['recordID']] = $recording;
345
    }
346
    return $recordsimportedarray;
347
}
348
349
/**
350
 * Helper function to retrive the default config.xml file.
351
 *
352
 * @return string
353
 */
354
function bigbluebuttonbn_get_default_config_xml() {
355
    $xml = bigbluebuttonbn_wrap_xml_load_file(
356
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getDefaultConfigXML')
357
    );
358
    return $xml;
359
}
360
361
/**
362
 * Helper function to convert an xml recording object to an array in the format used by the plugin.
363
 *
364
 * @param object $recording
365
 *
366
 * @return array
367
 */
368
function bigbluebuttonbn_get_recording_array_value($recording) {
369
    // Add formats.
370
    $playbackarray = array();
371
    foreach ($recording->playback->format as $format) {
372
        $playbackarray[(string) $format->type] = array('type' => (string) $format->type,
373
            'url' => trim((string) $format->url), 'length' => (string) $format->length);
374
        // Add preview per format when existing.
375
        if ($format->preview) {
376
            $playbackarray[(string) $format->type]['preview'] = bigbluebuttonbn_get_recording_preview_images($format->preview);
377
        }
378
    }
379
    // Add the metadata to the recordings array.
380
    $metadataarray = bigbluebuttonbn_get_recording_array_meta(get_object_vars($recording->metadata));
381
    $recordingarray = array('recordID' => (string) $recording->recordID,
382
        'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
383
        'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
384
        'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray);
385
    if (isset($recording->protected)) {
386
        $recordingarray['protected'] = (string) $recording->protected;
387
    }
388
    return $recordingarray + $metadataarray;
389
}
390
391
/**
392
 * Helper function to convert an xml recording preview images to an array in the format used by the plugin.
393
 *
394
 * @param object $preview
395
 *
396
 * @return array
397
 */
398
function bigbluebuttonbn_get_recording_preview_images($preview) {
399
    $imagesarray = array();
400
    foreach ($preview->images->image as $image) {
401
        $imagearray = array('url' => trim((string) $image));
402
        foreach ($image->attributes() as $attkey => $attvalue) {
403
            $imagearray[$attkey] = (string) $attvalue;
404
        }
405
        array_push($imagesarray, $imagearray);
406
    }
407
    return $imagesarray;
408
}
409
410
/**
411
 * Helper function to convert an xml recording metadata object to an array in the format used by the plugin.
412
 *
413
 * @param array $metadata
414
 *
415
 * @return array
416
 */
417
function bigbluebuttonbn_get_recording_array_meta($metadata) {
418
    $metadataarray = array();
419
    foreach ($metadata as $key => $value) {
420
        if (is_object($value)) {
421
            $value = '';
422
        }
423
        $metadataarray['meta_' . $key] = $value;
424
    }
425
    return $metadataarray;
426
}
427
428
/**
429
 * Helper function to sort an array of recordings. It compares the startTime in two recording objecs.
430
 *
431
 * @param object $a
432
 * @param object $b
433
 *
434
 * @return array
435
 */
436
function bigbluebuttonbn_recording_build_sorter($a, $b) {
437
    global $CFG;
438
    $resultless = !empty($CFG->bigbluebuttonbn_recordings_sortorder) ? -1 : 1;
439
    $resultmore = !empty($CFG->bigbluebuttonbn_recordings_sortorder) ? 1 : -1;
440
    if ($a['startTime'] < $b['startTime']) {
441
        return $resultless;
442
    }
443
    if ($a['startTime'] == $b['startTime']) {
444
        return 0;
445
    }
446
    return $resultmore;
447
}
448
449
/**
450
 * Perform deleteRecordings on BBB.
451
 *
452
 * @param string $recordids
453
 *
454
 * @return boolean
455
 */
456 View Code Duplication
function bigbluebuttonbn_delete_recordings($recordids) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
457
    $ids = explode(',', $recordids);
458
    foreach ($ids as $id) {
459
        $xml = bigbluebuttonbn_wrap_xml_load_file(
460
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('deleteRecordings', ['recordID' => $id])
461
        );
462
        if ($xml && $xml->returncode != 'SUCCESS') {
463
            return false;
464
        }
465
    }
466
    return true;
467
}
468
469
/**
470
 * Perform publishRecordings on BBB.
471
 *
472
 * @param string $recordids
473
 * @param string $publish
474
 */
475 View Code Duplication
function bigbluebuttonbn_publish_recordings($recordids, $publish = 'true') {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
476
    $ids = explode(',', $recordids);
477
    foreach ($ids as $id) {
478
        $xml = bigbluebuttonbn_wrap_xml_load_file(
479
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish])
480
        );
481
        if ($xml && $xml->returncode != 'SUCCESS') {
482
            return false;
483
        }
484
    }
485
    return true;
486
}
487
488
/**
489
 * Perform updateRecordings on BBB.
490
 *
491
 * @param string $recordids
492
 * @param array $params ['key'=>param_key, 'value']
493
 */
494 View Code Duplication
function bigbluebuttonbn_update_recordings($recordids, $params) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
495
    $ids = explode(',', $recordids);
496
    foreach ($ids as $id) {
497
        $xml = bigbluebuttonbn_wrap_xml_load_file(
498
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('updateRecordings', ['recordID' => $id] + (array) $params)
499
        );
500
        if ($xml && $xml->returncode != 'SUCCESS') {
501
            return false;
502
        }
503
    }
504
    return true;
505
}
506
507
/**
508
 * Perform end on BBB.
509
 *
510
 * @param string $meetingid
511
 * @param string $modpw
512
 */
513
function bigbluebuttonbn_end_meeting($meetingid, $modpw) {
514
    $xml = bigbluebuttonbn_wrap_xml_load_file(
515
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('end', ['meetingID' => $meetingid, 'password' => $modpw])
516
    );
517
    if ($xml) {
518
        // If the xml packet returned failure it displays the message to the user.
519
        return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
520
    }
521
    // If the server is unreachable, then prompts the user of the necessary action.
522
    return null;
523
}
524
525
/**
526
 * Perform api request on BBB.
527
 *
528
 * @return string
529
 */
530
function bigbluebuttonbn_get_server_version() {
531
    $xml = bigbluebuttonbn_wrap_xml_load_file(
532
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url()
533
    );
534
    if ($xml && $xml->returncode == 'SUCCESS') {
535
        return $xml->version;
536
    }
537
    return null;
538
}
539
540
/**
541
 * Perform api request on BBB and wraps the response in an XML object
542
 *
543
 * @param string $url
544
 * @param string $method
545
 * @param string $data
546
 * @param string $contenttype
547
 *
548
 * @return object
549
 */
550
function bigbluebuttonbn_wrap_xml_load_file($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
551
    if (extension_loaded('curl')) {
552
        $response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype);
553
        if (!$response) {
554
            debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER);
555
            return null;
556
        }
557
        $previous = libxml_use_internal_errors(true);
558
        try {
559
            $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
560
            return $xml;
561
        } catch (Exception $e) {
562
            libxml_use_internal_errors($previous);
563
            $error = 'Caught exception: ' . $e->getMessage();
564
            debugging($error, DEBUG_DEVELOPER);
565
            return null;
566
        }
567
    }
568
    // Alternative request non CURL based.
569
    $previous = libxml_use_internal_errors(true);
570
    try {
571
        $response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
572
        return $response;
573
    } catch (Exception $e) {
574
        $error = 'Caught exception: ' . $e->getMessage();
575
        debugging($error, DEBUG_DEVELOPER);
576
        libxml_use_internal_errors($previous);
577
        return null;
578
    }
579
}
580
581
/**
582
 * Perform api request on BBB using CURL and wraps the response in an XML object
583
 *
584
 * @param string $url
585
 * @param string $method
586
 * @param string $data
587
 * @param string $contenttype
588
 *
589
 * @return object
590
 */
591
function bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
592
    global $CFG;
593
    require_once($CFG->libdir . '/filelib.php');
594
    $c = new curl();
595
    $c->setopt(array('SSL_VERIFYPEER' => true));
596
    if ($method == 'POST') {
597
        if (is_null($data) || is_array($data)) {
598
            return $c->post($url);
599
        }
600
        $options = array();
601
        $options['CURLOPT_HTTPHEADER'] = array(
602
            'Content-Type: ' . $contenttype,
603
            'Content-Length: ' . strlen($data),
604
            'Content-Language: en-US',
605
        );
606
607
        return $c->post($url, $data, $options);
608
    }
609
    if ($method == 'HEAD') {
610
        $c->head($url, array('followlocation' => true, 'timeout' => 1));
611
        return $c->get_info();
612
    }
613
    return $c->get($url);
614
}
615
616
/**
617
 * End the session associated with this instance (if it's running).
618
 *
619
 * @param object $bigbluebuttonbn
620
 *
621
 * @return void
622
 */
623
function bigbluebuttonbn_end_meeting_if_running($bigbluebuttonbn) {
624
    $meetingid = $bigbluebuttonbn->meetingid . '-' . $bigbluebuttonbn->course . '-' . $bigbluebuttonbn->id;
625
    if (bigbluebuttonbn_is_meeting_running($meetingid)) {
626
        bigbluebuttonbn_end_meeting($meetingid, $bigbluebuttonbn->moderatorpass);
627
    }
628
}
629
630
/**
631
 * Returns user roles in a context.
632
 *
633
 * @param object $context
634
 * @param integer $userid
635
 *
636
 * @return array $userroles
637
 */
638
function bigbluebuttonbn_get_user_roles($context, $userid) {
639
    global $DB;
640
    $userroles = get_user_roles($context, $userid);
641
    if ($userroles) {
642
        $where = '';
643
        foreach ($userroles as $userrole) {
644
            $where .= (empty($where) ? ' WHERE' : ' OR') . ' id=' . $userrole->roleid;
645
        }
646
        $userroles = $DB->get_records_sql('SELECT * FROM {role}' . $where);
647
    }
648
    return $userroles;
649
}
650
651
/**
652
 * Returns guest role wrapped in an array.
653
 *
654
 * @return array
655
 */
656
function bigbluebuttonbn_get_guest_role() {
657
    $guestrole = get_guest_role();
658
    return array($guestrole->id => $guestrole);
659
}
660
661
/**
662
 * Returns an array containing all the users in a context.
663
 *
664
 * @param context $context
665
 *
666
 * @return array $users
667
 */
668
function bigbluebuttonbn_get_users(context $context = null) {
669
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
670
    foreach ($users as $key => $value) {
671
        $users[$key] = fullname($value);
672
    }
673
    return $users;
674
}
675
676
/**
677
 * Returns an array containing all the users in a context wrapped for html select element.
678
 *
679
 * @param context_course $context
680
 * @param null $bbactivity
681
 * @return array $users
682
 * @throws coding_exception
683
 * @throws moodle_exception
684
 */
685
function bigbluebuttonbn_get_users_select(context_course $context, $bbactivity = null) {
686
    // CONTRIB-7972, check the group of current user and course group mode.
687
    $groups = null;
0 ignored issues
show
Unused Code introduced by
$groups is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
688
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
689
    $course = get_course($context->instanceid);
690
    $groupmode = groups_get_course_groupmode($course);
691
    if ($bbactivity) {
692
        list($bbcourse, $cm) = get_course_and_cm_from_instance($bbactivity->id, 'bigbluebuttonbn');
0 ignored issues
show
Unused Code introduced by
The assignment to $bbcourse is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
693
        $groupmode = groups_get_activity_groupmode($cm);
694
695
    }
696
    if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $context)) {
697
        global $USER;
698
        $groups = groups_get_all_groups($course->id, $USER->id);
699
        $users = [];
700
        foreach ($groups as $g) {
701
            $users += (array) get_enrolled_users($context, '', $g->id, 'u.*', null, 0, 0, true);
702
        }
703
    }
704
    return array_map(
705
            function($u) {
706
                return array('id' => $u->id, 'name' => fullname($u));
707
            },
708
            $users);
709
}
710
711
/**
712
 * Returns an array containing all the roles in a context.
713
 *
714
 * @param context $context
715
 *
716
 * @return array $roles
717
 */
718
function bigbluebuttonbn_get_roles(context $context = null) {
719
    $roles = (array) role_get_names($context);
720
    foreach ($roles as $key => $value) {
721
        $roles[$key] = $value->localname;
722
    }
723
    return $roles;
724
}
725
726
/**
727
 * Returns an array containing all the roles in a context wrapped for html select element.
728
 *
729
 * @param context $context
730
 *
731
 * @return array $users
732
 */
733
function bigbluebuttonbn_get_roles_select(context $context = null) {
734
    $roles = (array) role_get_names($context);
735
    foreach ($roles as $key => $value) {
736
        $roles[$key] = array('id' => $value->id, 'name' => $value->localname);
737
    }
738
    return $roles;
739
}
740
741
/**
742
 * Returns role that corresponds to an id.
743
 *
744
 * @param string|integer $id
745
 *
746
 * @return object $role
747
 */
748
function bigbluebuttonbn_get_role($id) {
749
    $roles = (array) role_get_names();
750
    if (is_numeric($id) && isset($roles[$id])) {
751
        return (object) $roles[$id];
752
    }
753
    foreach ($roles as $role) {
754
        if ($role->shortname == $id) {
755
            return $role;
756
        }
757
    }
758
}
759
760
/**
761
 * Returns an array to populate a list of participants used in mod_form.js.
762
 *
763
 * @param context $context
764
 * @param null|object $bbactivity
765
 * @return array $data
766
 */
767
function bigbluebuttonbn_get_participant_data($context, $bbactivity = null) {
768
    $data = array(
769
        'all' => array(
770
            'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
771
            'children' => []
772
        ),
773
    );
774
    $data['role'] = array(
775
        'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
776
        'children' => bigbluebuttonbn_get_roles_select($context),
777
    );
778
    $data['user'] = array(
779
        'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
780
        'children' => bigbluebuttonbn_get_users_select($context, $bbactivity),
0 ignored issues
show
Bug introduced by
It seems like $bbactivity defined by parameter $bbactivity on line 767 can also be of type object; however, bigbluebuttonbn_get_users_select() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
781
    );
782
    return $data;
783
}
784
785
/**
786
 * Returns an array to populate a list of participants used in mod_form.php.
787
 *
788
 * @param object $bigbluebuttonbn
789
 * @param context $context
790
 *
791
 * @return array
792
 */
793
function bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context) {
794
    global $USER;
795
    if ($bigbluebuttonbn == null) {
796
        return bigbluebuttonbn_get_participant_rules_encoded(
797
            bigbluebuttonbn_get_participant_list_default($context, $USER->id)
798
        );
799
    }
800
    if (empty($bigbluebuttonbn->participants)) {
801
        $bigbluebuttonbn->participants = "[]";
802
    }
803
    $rules = json_decode($bigbluebuttonbn->participants, true);
804
    if (empty($rules)) {
805
        $rules = bigbluebuttonbn_get_participant_list_default($context, bigbluebuttonbn_instance_ownerid($bigbluebuttonbn));
806
    }
807
    return bigbluebuttonbn_get_participant_rules_encoded($rules);
808
}
809
810
/**
811
 * Returns an array to populate a list of participants used in mod_form.php with default values.
812
 *
813
 * @param context $context
814
 * @param integer $ownerid
815
 *
816
 * @return array
817
 */
818
function bigbluebuttonbn_get_participant_list_default($context, $ownerid = null) {
819
    $participantlist = array();
820
    $participantlist[] = array(
821
        'selectiontype' => 'all',
822
        'selectionid' => 'all',
823
        'role' => BIGBLUEBUTTONBN_ROLE_VIEWER,
824
    );
825
    $defaultrules = explode(',', \mod_bigbluebuttonbn\locallib\config::get('participant_moderator_default'));
826
    foreach ($defaultrules as $defaultrule) {
827
        if ($defaultrule == '0') {
828
            if (!empty($ownerid) && is_enrolled($context, $ownerid)) {
829
                $participantlist[] = array(
830
                    'selectiontype' => 'user',
831
                    'selectionid' => (string) $ownerid,
832
                    'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
833
            }
834
            continue;
835
        }
836
        $participantlist[] = array(
837
            'selectiontype' => 'role',
838
            'selectionid' => $defaultrule,
839
            'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
840
    }
841
    return $participantlist;
842
}
843
844
/**
845
 * Returns an array to populate a list of participants used in mod_form.php with bigbluebuttonbn values.
846
 *
847
 * @param array $rules
848
 *
849
 * @return array
850
 */
851
function bigbluebuttonbn_get_participant_rules_encoded($rules) {
852
    foreach ($rules as $key => $rule) {
853
        if ($rule['selectiontype'] !== 'role' || is_numeric($rule['selectionid'])) {
854
            continue;
855
        }
856
        $role = bigbluebuttonbn_get_role($rule['selectionid']);
857
        if ($role == null) {
858
            unset($rules[$key]);
859
            continue;
860
        }
861
        $rule['selectionid'] = $role->id;
862
        $rules[$key] = $rule;
863
    }
864
    return $rules;
865
}
866
867
/**
868
 * Returns an array to populate a list of participant_selection used in mod_form.php.
869
 *
870
 * @return array
871
 */
872
function bigbluebuttonbn_get_participant_selection_data() {
873
    return [
874
        'type_options' => [
875
            'all' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
876
            'role' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
877
            'user' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
878
        ],
879
        'type_selected' => 'all',
880
        'options' => ['all' => '---------------'],
881
        'selected' => 'all',
882
    ];
883
}
884
885
/**
886
 * Evaluate if a user in a context is moderator based on roles and participation rules.
887
 *
888
 * @param context $context
889
 * @param array $participantlist
890
 * @param integer $userid
891
 *
892
 * @return boolean
893
 */
894
function bigbluebuttonbn_is_moderator($context, $participantlist, $userid = null) {
895
    global $USER;
896
    if (!is_array($participantlist)) {
897
        return false;
898
    }
899
    if (empty($userid)) {
900
        $userid = $USER->id;
901
    }
902
    $userroles = bigbluebuttonbn_get_guest_role();
903
    if (!isguestuser()) {
904
        $userroles = bigbluebuttonbn_get_user_roles($context, $userid);
905
    }
906
    return bigbluebuttonbn_is_moderator_validator($participantlist, $userid, $userroles);
907
}
908
909
/**
910
 * Iterates participant list rules to evaluate if a user is moderator.
911
 *
912
 * @param array $participantlist
913
 * @param integer $userid
914
 * @param array $userroles
915
 *
916
 * @return boolean
917
 */
918
function bigbluebuttonbn_is_moderator_validator($participantlist, $userid, $userroles) {
919
    // Iterate participant rules.
920
    foreach ($participantlist as $participant) {
921
        if (bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles)) {
922
            return true;
923
        }
924
    }
925
    return false;
926
}
927
928
/**
929
 * Evaluate if a user is moderator based on roles and a particular participation rule.
930
 *
931
 * @param object $participant
932
 * @param integer $userid
933
 * @param array $userroles
934
 *
935
 * @return boolean
936
 */
937
function bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles) {
938
    if ($participant['role'] == BIGBLUEBUTTONBN_ROLE_VIEWER) {
939
        return false;
940
    }
941
    // Validation for the 'all' rule.
942
    if ($participant['selectiontype'] == 'all') {
943
        return true;
944
    }
945
    // Validation for a 'user' rule.
946
    if ($participant['selectiontype'] == 'user') {
947
        if ($participant['selectionid'] == $userid) {
948
            return true;
949
        }
950
        return false;
951
    }
952
    // Validation for a 'role' rule.
953
    $role = bigbluebuttonbn_get_role($participant['selectionid']);
954
    if ($role != null && array_key_exists($role->id, $userroles)) {
955
        return true;
956
    }
957
    return false;
958
}
959
960
/**
961
 * Helper returns error message key for the language file that corresponds to a bigbluebutton error key.
962
 *
963
 * @param string $messagekey
964
 * @param string $defaultkey
965
 *
966
 * @return string
967
 */
968
function bigbluebuttonbn_get_error_key($messagekey, $defaultkey = null) {
969
    if ($messagekey == 'checksumError') {
970
        return 'index_error_checksum';
971
    }
972
    if ($messagekey == 'maxConcurrent') {
973
        return 'view_error_max_concurrent';
974
    }
975
    return $defaultkey;
976
}
977
978
/**
979
 * Helper evaluates if a voicebridge number is unique.
980
 *
981
 * @param integer $instance
982
 * @param integer $voicebridge
983
 *
984
 * @return string
985
 */
986
function bigbluebuttonbn_voicebridge_unique($instance, $voicebridge) {
987
    global $DB;
988
    if ($voicebridge == 0) {
989
        return true;
990
    }
991
    $select = 'voicebridge = ' . $voicebridge;
992
    if ($instance != 0) {
993
        $select .= ' AND id <>' . $instance;
994
    }
995
    if (!$DB->get_records_select('bigbluebuttonbn', $select)) {
996
        return true;
997
    }
998
    return false;
999
}
1000
1001
/**
1002
 * Helper estimate a duration for the meeting based on the closingtime.
1003
 *
1004
 * @param integer $closingtime
1005
 *
1006
 * @return integer
1007
 */
1008
function bigbluebuttonbn_get_duration($closingtime) {
1009
    $duration = 0;
1010
    $now = time();
1011
    if ($closingtime > 0 && $now < $closingtime) {
1012
        $duration = ceil(($closingtime - $now) / 60);
1013
        $compensationtime = intval((int) \mod_bigbluebuttonbn\locallib\config::get('scheduled_duration_compensation'));
1014
        $duration = intval($duration) + $compensationtime;
1015
    }
1016
    return $duration;
1017
}
1018
1019
/**
1020
 * Helper return array containing the file descriptor for a preuploaded presentation.
1021
 *
1022
 * @param context $context
1023
 * @param string $presentation
1024
 * @param integer $id
1025
 *
1026
 * @return array
1027
 */
1028
function bigbluebuttonbn_get_presentation_array($context, $presentation, $id = null) {
1029
    global $CFG;
1030
    if (empty($presentation)) {
1031
        if ($CFG->bigbluebuttonbn_preuploadpresentation_enabled) {
1032
            // Item has not presentation but presentation is enabled..
1033
            // Check if exist some file by default in general mod setting ("presentationdefault").
1034
            $fs = get_file_storage();
1035
            $files = $fs->get_area_files(
1036
                context_system::instance()->id,
1037
                'mod_bigbluebuttonbn',
1038
                'presentationdefault',
1039
                0,
1040
                "filename",
1041
                false
1042
            );
1043
1044 View Code Duplication
            if (count($files) == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1045
                // Not exist file by default in "presentationbydefault" setting.
1046
                return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
1047
            }
1048
1049
            // Exists file in general setting to use as default for presentation. Cache image for temp public access.
1050
            $file = reset($files);
1051
            unset($files);
1052
            $pnoncevalue = null;
1053 View Code Duplication
            if (!is_null($id)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1054
                // Create the nonce component for granting a temporary public access.
1055
                $cache = cache::make_from_params(
1056
                    cache_store::MODE_APPLICATION,
1057
                    'mod_bigbluebuttonbn',
1058
                    'presentationdefault_cache'
1059
                );
1060
                $pnoncekey = sha1(context_system::instance()->id);
1061
                /* The item id was adapted for granting public access to the presentation once in order
1062
                 * to allow BigBlueButton to gather the file. */
1063
                $pnoncevalue = bigbluebuttonbn_generate_nonce();
1064
                $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
1065
            }
1066
1067
            $url = moodle_url::make_pluginfile_url(
1068
                $file->get_contextid(),
1069
                $file->get_component(),
1070
                $file->get_filearea(),
1071
                $pnoncevalue,
1072
                $file->get_filepath(),
1073
                $file->get_filename()
1074
            );
1075
            return (array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
1076
                'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file)));
1077
        }
1078
1079
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
1080
    }
1081
    $fs = get_file_storage();
1082
    $files = $fs->get_area_files(
1083
        $context->id,
1084
        'mod_bigbluebuttonbn',
1085
        'presentation',
1086
        0,
1087
        'itemid, filepath, filename',
1088
        false
1089
    );
1090 View Code Duplication
    if (count($files) == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1091
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
1092
    }
1093
    $file = reset($files);
1094
    unset($files);
1095
    $pnoncevalue = null;
1096 View Code Duplication
    if (!is_null($id)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1097
        // Create the nonce component for granting a temporary public access.
1098
        $cache = cache::make_from_params(
1099
            cache_store::MODE_APPLICATION,
1100
            'mod_bigbluebuttonbn',
1101
            'presentation_cache'
1102
        );
1103
        $pnoncekey = sha1($id);
1104
        /* The item id was adapted for granting public access to the presentation once in order
1105
         * to allow BigBlueButton to gather the file. */
1106
        $pnoncevalue = bigbluebuttonbn_generate_nonce();
1107
        $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
1108
    }
1109
    $url = moodle_url::make_pluginfile_url(
1110
        $file->get_contextid(),
1111
        $file->get_component(),
1112
        $file->get_filearea(),
1113
        $pnoncevalue,
1114
        $file->get_filepath(),
1115
        $file->get_filename()
1116
    );
1117
    return array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
1118
        'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file));
1119
}
1120
1121
/**
1122
 * Helper generates a nonce used for the preuploaded presentation callback url.
1123
 *
1124
 * @return string
1125
 */
1126
function bigbluebuttonbn_generate_nonce() {
1127
    $mt = microtime();
1128
    $rand = mt_rand();
1129
    return md5($mt . $rand);
1130
}
1131
1132
/**
1133
 * Helper generates a random password.
1134
 *
1135
 * @param integer $length
1136
 * @param string $unique
1137
 *
1138
 * @return string
1139
 */
1140
function bigbluebuttonbn_random_password($length = 8, $unique = "") {
1141
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1142
    do {
1143
        $password = substr(str_shuffle($chars), 0, $length);
1144
    } while ($unique == $password);
1145
    return $password;
1146
}
1147
1148
/**
1149
 * Helper register a bigbluebuttonbn event.
1150
 *
1151
 * @param string $type
1152
 * @param object $bigbluebuttonbn
1153
 * @param array $options [timecreated, userid, other]
1154
 *
1155
 * @return void
1156
 */
1157
function bigbluebuttonbn_event_log($type, $bigbluebuttonbn, $options = []) {
1158
    global $DB;
1159
    if (!in_array($type, \mod_bigbluebuttonbn\event\events::$events)) {
1160
        // No log will be created.
1161
        return;
1162
    }
1163
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
1164
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
1165
    $context = context_module::instance($cm->id);
1166
    $params = array('context' => $context, 'objectid' => $bigbluebuttonbn->id);
1167
    if (array_key_exists('timecreated', $options)) {
1168
        $params['timecreated'] = $options['timecreated'];
1169
    }
1170
    if (array_key_exists('userid', $options)) {
1171
        $params['userid'] = $options['userid'];
1172
    }
1173
    if (array_key_exists('other', $options)) {
1174
        $params['other'] = $options['other'];
1175
    }
1176
    $event = call_user_func_array(
1177
        '\mod_bigbluebuttonbn\event\\' . $type . '::create',
1178
        array($params)
1179
    );
1180
    $event->add_record_snapshot('course_modules', $cm);
1181
    $event->add_record_snapshot('course', $course);
1182
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
1183
    $event->trigger();
1184
}
1185
1186
/**
1187
 * Updates the meeting info cached object when a participant has joined.
1188
 *
1189
 * @param string $meetingid
1190
 * @param bool $ismoderator
1191
 *
1192
 * @return void
1193
 */
1194
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) {
1195
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1196
    $result = $cache->get($meetingid);
1197
    $meetinginfo = json_decode($result['meeting_info']);
1198
    $meetinginfo->participantCount += 1;
1199
    if ($ismoderator) {
1200
        $meetinginfo->moderatorCount += 1;
1201
    }
1202
    $cache->set($meetingid, array('creation_time' => $result['creation_time'],
1203
        'meeting_info' => json_encode($meetinginfo)));
1204
}
1205
1206
/**
1207
 * Gets a meeting info object cached or fetched from the live session.
1208
 *
1209
 * @param string $meetingid
1210
 * @param boolean $updatecache
1211
 *
1212
 * @return array
1213
 */
1214
function bigbluebuttonbn_get_meeting_info($meetingid, $updatecache = false) {
1215
    $cachettl = (int) \mod_bigbluebuttonbn\locallib\config::get('waitformoderator_cache_ttl');
1216
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1217
    $result = $cache->get($meetingid);
1218
    $now = time();
1219
    if (!$updatecache && isset($result) && $now < ($result['creation_time'] + $cachettl)) {
1220
        // Use the value in the cache.
1221
        return (array) json_decode($result['meeting_info']);
1222
    }
1223
    // Ping again and refresh the cache.
1224
    $meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file(
1225
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
1226
    );
1227
    $cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo)));
1228
    return $meetinginfo;
1229
}
1230
1231
/**
1232
 * Perform isMeetingRunning on BBB.
1233
 *
1234
 * @param string $meetingid
1235
 * @param boolean $updatecache
1236
 *
1237
 * @return boolean
1238
 */
1239
function bigbluebuttonbn_is_meeting_running($meetingid, $updatecache = false) {
1240
    /* As a workaround to isMeetingRunning that always return SUCCESS but only returns true
1241
     * when at least one user is in the session, we use getMeetingInfo instead.
1242
     */
1243
    $meetinginfo = bigbluebuttonbn_get_meeting_info($meetingid, $updatecache);
1244
    return ($meetinginfo['returncode'] === 'SUCCESS');
1245
}
1246
1247
/**
1248
 * Publish an imported recording.
1249
 *
1250
 * @param string $id
1251
 * @param boolean $publish
1252
 *
1253
 * @return boolean
1254
 */
1255 View Code Duplication
function bigbluebuttonbn_publish_recording_imported($id, $publish = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1256
    global $DB;
1257
    // Locate the record to be updated.
1258
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1259
    $meta = json_decode($record->meta, true);
1260
    // Prepare data for the update.
1261
    $meta['recording']['published'] = ($publish) ? 'true' : 'false';
1262
    $record->meta = json_encode($meta);
1263
    // Proceed with the update.
1264
    $DB->update_record('bigbluebuttonbn_logs', $record);
1265
    return true;
1266
}
1267
1268
/**
1269
 * Delete an imported recording.
1270
 *
1271
 * @param string $id
1272
 *
1273
 * @return boolean
1274
 */
1275
function bigbluebuttonbn_delete_recording_imported($id) {
1276
    global $DB;
1277
    // Execute delete.
1278
    $DB->delete_records('bigbluebuttonbn_logs', array('id' => $id));
1279
    return true;
1280
}
1281
1282
/**
1283
 * Update an imported recording.
1284
 *
1285
 * @param string $id
1286
 * @param array $params ['key'=>param_key, 'value']
1287
 *
1288
 * @return boolean
1289
 */
1290
function bigbluebuttonbn_update_recording_imported($id, $params) {
1291
    global $DB;
1292
    // Locate the record to be updated.
1293
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1294
    $meta = json_decode($record->meta, true);
1295
    // Prepare data for the update.
1296
    $meta['recording'] = $params + $meta['recording'];
1297
    $record->meta = json_encode($meta);
1298
    // Proceed with the update.
1299
    if (!$DB->update_record('bigbluebuttonbn_logs', $record)) {
1300
        return false;
1301
    }
1302
    return true;
1303
}
1304
1305
/**
1306
 * Protect/Unprotect an imported recording.
1307
 *
1308
 * @param string $id
1309
 * @param boolean $protect
1310
 *
1311
 * @return boolean
1312
 */
1313 View Code Duplication
function bigbluebuttonbn_protect_recording_imported($id, $protect = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1314
    global $DB;
1315
    // Locate the record to be updated.
1316
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1317
    $meta = json_decode($record->meta, true);
1318
    // Prepare data for the update.
1319
    $meta['recording']['protected'] = ($protect) ? 'true' : 'false';
1320
    $record->meta = json_encode($meta);
1321
    // Proceed with the update.
1322
    $DB->update_record('bigbluebuttonbn_logs', $record);
1323
    return true;
1324
}
1325
1326
/**
1327
 * Sets a custom config.xml file for being used on create.
1328
 *
1329
 * @param string $meetingid
1330
 * @param string $configxml
1331
 *
1332
 * @return object
1333
 */
1334
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) {
1335
    $urldefaultconfig = \mod_bigbluebuttonbn\locallib\config::get('server_url') . 'api/setConfigXML?';
1336
    $configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml);
1337
    $xml = bigbluebuttonbn_wrap_xml_load_file(
1338
        $urldefaultconfig,
1339
        'POST',
1340
        $configxmlparams,
1341
        'application/x-www-form-urlencoded'
1342
    );
1343
    return $xml;
1344
}
1345
1346
/**
1347
 * Sets qs used with a custom config.xml file request.
1348
 *
1349
 * @param string $meetingid
1350
 * @param string $configxml
1351
 *
1352
 * @return string
1353
 */
1354
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) {
1355
    $params = 'configXML=' . urlencode($configxml) . '&meetingID=' . urlencode($meetingid);
1356
    $sharedsecret = \mod_bigbluebuttonbn\locallib\config::get('shared_secret');
1357
    $configxmlparams = $params . '&checksum=' . sha1('setConfigXML' . $params . $sharedsecret);
1358
    return $configxmlparams;
1359
}
1360
1361
/**
1362
 * Sets a custom config.xml file for being used on create.
1363
 *
1364
 * @param string $meetingid
1365
 * @param string $configxml
1366
 *
1367
 * @return array
1368
 */
1369
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) {
1370
    $configxml = bigbluebuttonbn_setConfigXML($meetingid, $configxml);
1371
    $configxmlarray = (array) $configxml;
1372
    if ($configxmlarray['returncode'] != 'SUCCESS') {
1373
        debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER);
1374
        return '';
1375
    }
1376
    return $configxmlarray['configToken'];
1377
}
1378
1379
/**
1380
 * Helper function builds a row for the data used by the recording table.
1381
 *
1382
 * @param array $bbbsession
1383
 * @param array $recording
1384
 * @param array $tools
1385
 *
1386
 * @return array
1387
 */
1388
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['protect', 'publish', 'delete']) {
1389
    if (!bigbluebuttonbn_include_recording_table_row($bbbsession, $recording)) {
1390
        return;
1391
    }
1392
    $rowdata = new stdClass();
1393
    // Set recording_types.
1394
    $rowdata->playback = bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession);
1395
    // Set activity name.
1396
    $rowdata->recording = bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession);
1397
    // Set activity description.
1398
    $rowdata->description = bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession);
1399
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1400
        // Set recording_preview.
1401
        $rowdata->preview = bigbluebuttonbn_get_recording_data_row_preview($recording);
1402
    }
1403
    // Set date.
1404
    $rowdata->date = bigbluebuttonbn_get_recording_data_row_date($recording);
1405
    // Set formatted date.
1406
    $rowdata->date_formatted = bigbluebuttonbn_get_recording_data_row_date_formatted($rowdata->date);
1407
    // Set formatted duration.
1408
    $rowdata->duration_formatted = $rowdata->duration = bigbluebuttonbn_get_recording_data_row_duration($recording);
1409
    // Set actionbar, if user is allowed to manage recordings.
1410
    if ($bbbsession['managerecordings']) {
1411
        $rowdata->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools);
1412
    }
1413
    return $rowdata;
1414
}
1415
1416
/**
1417
 * Helper function evaluates if a row for the data used by the recording table is editable.
1418
 *
1419
 * @param array $bbbsession
1420
 *
1421
 * @return boolean
1422
 */
1423
function bigbluebuttonbn_get_recording_data_row_editable($bbbsession) {
1424
    return ($bbbsession['managerecordings'] && ((double) $bbbsession['serverversion'] >= 1.0 || $bbbsession['bnserver']));
1425
}
1426
1427
/**
1428
 * Helper function evaluates if recording preview should be included.
1429
 *
1430
 * @param array $bbbsession
1431
 *
1432
 * @return boolean
1433
 */
1434
function bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession) {
1435
    return ((double) $bbbsession['serverversion'] >= 1.0 && $bbbsession['bigbluebuttonbn']->recordings_preview == '1');
1436
}
1437
1438
/**
1439
 * Helper function converts recording date used in row for the data used by the recording table.
1440
 *
1441
 * @param array $recording
1442
 *
1443
 * @return integer
1444
 */
1445
function bigbluebuttonbn_get_recording_data_row_date($recording) {
1446
    if (!isset($recording['startTime'])) {
1447
        return 0;
1448
    }
1449
    return floatval($recording['startTime']);
1450
}
1451
1452
/**
1453
 * Helper function format recording date used in row for the data used by the recording table.
1454
 *
1455
 * @param integer $starttime
1456
 *
1457
 * @return string
1458
 */
1459
function bigbluebuttonbn_get_recording_data_row_date_formatted($starttime) {
1460
    global $USER;
1461
    $starttime = $starttime - ($starttime % 1000);
1462
    // Set formatted date.
1463
    $dateformat = get_string('strftimerecentfull', 'langconfig') . ' %Z';
1464
    return userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone));
1465
}
1466
1467
/**
1468
 * Helper function converts recording duration used in row for the data used by the recording table.
1469
 *
1470
 * @param array $recording
1471
 *
1472
 * @return integer
1473
 */
1474
function bigbluebuttonbn_get_recording_data_row_duration($recording) {
1475
    foreach (array_values($recording['playbacks']) as $playback) {
1476
        // Ignore restricted playbacks.
1477
        if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'true') {
1478
            continue;
1479
        }
1480
        // Take the lenght form the fist playback with an actual value.
1481
        if (!empty($playback['length'])) {
1482
            return intval($playback['length']);
1483
        }
1484
    }
1485
    return 0;
1486
}
1487
1488
/**
1489
 * Helper function builds recording actionbar used in row for the data used by the recording table.
1490
 *
1491
 * @param array $recording
1492
 * @param array $tools
1493
 *
1494
 * @return string
1495
 */
1496
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) {
1497
    $actionbar = '';
1498
    foreach ($tools as $tool) {
1499
        $buttonpayload = bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool);
1500
        if ($tool == 'protect') {
1501
            if (isset($recording['imported'])) {
1502
                $buttonpayload['disabled'] = 'disabled';
1503
            }
1504
            if (!isset($recording['protected'])) {
1505
                $buttonpayload['disabled'] = 'invisible';
1506
            }
1507
        }
1508
        $actionbar .= bigbluebuttonbn_actionbar_render_button($recording, $buttonpayload);
1509
    }
1510
    $head = html_writer::start_tag('div', array(
1511
        'id' => 'recording-actionbar-' . $recording['recordID'],
1512
        'data-recordingid' => $recording['recordID'],
1513
        'data-meetingid' => $recording['meetingID']));
1514
    $tail = html_writer::end_tag('div');
1515
    return $head . $actionbar . $tail;
1516
}
1517
1518
/**
1519
 * Helper function returns the corresponding payload for an actionbar button used in row
1520
 * for the data used by the recording table.
1521
 *
1522
 * @param array $recording
1523
 * @param array $tool
1524
 *
1525
 * @return array
1526
 */
1527
function bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool) {
1528
    if ($tool == 'protect') {
1529
        $protected = 'false';
1530
        if (isset($recording['protected'])) {
1531
            $protected = $recording['protected'];
1532
        }
1533
        return bigbluebuttonbn_get_recording_data_row_action_protect($protected);
1534
    }
1535
    if ($tool == 'publish') {
1536
        return bigbluebuttonbn_get_recording_data_row_action_publish($recording['published']);
1537
    }
1538
    return array('action' => $tool, 'tag' => $tool);
1539
}
1540
1541
/**
1542
 * Helper function returns the payload for protect action button used in row
1543
 * for the data used by the recording table.
1544
 *
1545
 * @param string $protected
1546
 *
1547
 * @return array
1548
 */
1549
function bigbluebuttonbn_get_recording_data_row_action_protect($protected) {
1550
    if ($protected == 'true') {
1551
        return array('action' => 'unprotect', 'tag' => 'lock');
1552
    }
1553
    return array('action' => 'protect', 'tag' => 'unlock');
1554
}
1555
1556
/**
1557
 * Helper function returns the payload for publish action button used in row
1558
 * for the data used by the recording table.
1559
 *
1560
 * @param string $published
1561
 *
1562
 * @return array
1563
 */
1564
function bigbluebuttonbn_get_recording_data_row_action_publish($published) {
1565
    if ($published == 'true') {
1566
        return array('action' => 'unpublish', 'tag' => 'hide');
1567
    }
1568
    return array('action' => 'publish', 'tag' => 'show');
1569
}
1570
1571
/**
1572
 * Helper function builds recording preview used in row for the data used by the recording table.
1573
 *
1574
 * @param array $recording
1575
 *
1576
 * @return string
1577
 */
1578
function bigbluebuttonbn_get_recording_data_row_preview($recording) {
1579
    $options = array('id' => 'preview-' . $recording['recordID']);
1580
    if ($recording['published'] === 'false') {
1581
        $options['hidden'] = 'hidden';
1582
    }
1583
    $recordingpreview = html_writer::start_tag('div', $options);
1584
    foreach ($recording['playbacks'] as $playback) {
1585
        if (isset($playback['preview'])) {
1586
            $recordingpreview .= bigbluebuttonbn_get_recording_data_row_preview_images($playback);
1587
            break;
1588
        }
1589
    }
1590
    $recordingpreview .= html_writer::end_tag('div');
1591
    return $recordingpreview;
1592
}
1593
1594
/**
1595
 * Helper function builds element with actual images used in recording preview row based on a selected playback.
1596
 *
1597
 * @param array $playback
1598
 *
1599
 * @return string
1600
 */
1601
function bigbluebuttonbn_get_recording_data_row_preview_images($playback) {
1602
    global $CFG;
1603
    $recordingpreview  = html_writer::start_tag('div', array('class' => 'container-fluid'));
1604
    $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1605
    foreach ($playback['preview'] as $image) {
1606
        if ($CFG->bigbluebuttonbn_recordings_validate_url && !bigbluebuttonbn_is_valid_resource(trim($image['url']))) {
1607
            return '';
1608
        }
1609
        $recordingpreview .= html_writer::start_tag('div', array('class' => ''));
1610
        $recordingpreview .= html_writer::empty_tag(
1611
            'img',
1612
            array('src' => trim($image['url']) . '?' . time(), 'class' => 'recording-thumbnail pull-left')
1613
        );
1614
        $recordingpreview .= html_writer::end_tag('div');
1615
    }
1616
    $recordingpreview .= html_writer::end_tag('div');
1617
    $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1618
    $recordingpreview .= html_writer::tag(
1619
        'div',
1620
        get_string('view_recording_preview_help', 'bigbluebuttonbn'),
1621
        array('class' => 'text-center text-muted small')
1622
    );
1623
    $recordingpreview .= html_writer::end_tag('div');
1624
    $recordingpreview .= html_writer::end_tag('div');
1625
    return $recordingpreview;
1626
}
1627
1628
/**
1629
 * Helper function renders recording types to be used in row for the data used by the recording table.
1630
 *
1631
 * @param array $recording
1632
 * @param array $bbbsession
1633
 *
1634
 * @return string
1635
 */
1636
function bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession) {
1637
    $dataimported = 'false';
1638
    $title = '';
1639
    if (isset($recording['imported'])) {
1640
        $dataimported = 'true';
1641
        $title = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1642
    }
1643
    $visibility = '';
1644
    if ($recording['published'] === 'false') {
1645
        $visibility = 'hidden ';
1646
    }
1647
    $id = 'playbacks-' . $recording['recordID'];
1648
    $recordingtypes = html_writer::start_tag('div', array('id' => $id, 'data-imported' => $dataimported,
1649
        'data-meetingid' => $recording['meetingID'], 'data-recordingid' => $recording['recordID'],
1650
        'title' => $title, $visibility => $visibility));
1651
    foreach ($recording['playbacks'] as $playback) {
1652
        $recordingtypes .= bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback);
1653
    }
1654
    $recordingtypes .= html_writer::end_tag('div');
1655
    return $recordingtypes;
1656
}
1657
1658
/**
1659
 * Helper function renders the link used for recording type in row for the data used by the recording table.
1660
 *
1661
 * @param array $recording
1662
 * @param array $bbbsession
1663
 * @param array $playback
1664
 *
1665
 * @return string
1666
 */
1667
function bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback) {
1668
    global $CFG, $OUTPUT;
1669
    if (!bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback)) {
1670
        return '';
1671
    }
1672
    $text = bigbluebuttonbn_get_recording_type_text($playback['type']);
1673
    $href = $CFG->wwwroot . '/mod/bigbluebuttonbn/bbb_view.php?action=play&bn=' . $bbbsession['bigbluebuttonbn']->id .
1674
        '&mid=' . $recording['meetingID'] . '&rid=' . $recording['recordID'] . '&rtype=' . $playback['type'];
1675
    if (!isset($recording['imported']) || !isset($recording['protected']) || $recording['protected'] === 'false') {
1676
        $href .= '&href=' . urlencode(trim($playback['url']));
1677
    }
1678
    $linkattributes = array(
1679
        'id' => 'recording-play-' . $playback['type'] . '-' . $recording['recordID'],
1680
        'class' => 'btn btn-sm btn-default',
1681
        'onclick' => 'M.mod_bigbluebuttonbn.recordings.recordingPlay(this);',
1682
        'data-action' => 'play',
1683
        'data-target' => $playback['type'],
1684
        'data-href' => $href,
1685
      );
1686
    if ($CFG->bigbluebuttonbn_recordings_validate_url && !bigbluebuttonbn_is_bn_server() && !bigbluebuttonbn_is_valid_resource(trim($playback['url']))) {
1687
        $linkattributes['class'] = 'btn btn-sm btn-warning';
1688
        $linkattributes['title'] = get_string('view_recording_format_errror_unreachable', 'bigbluebuttonbn');
1689
        unset($linkattributes['data-href']);
1690
    }
1691
    return $OUTPUT->action_link('#', $text, null, $linkattributes) . '&#32;';
1692
}
1693
1694
/**
1695
 * Helper function to handle yet unknown recording types
1696
 *
1697
 * @param string $playbacktype : for now presentation, video, statistics, capture, notes, podcast
1698
 *
1699
 * @return string the matching language string or a capitalised version of the provided string
1700
 */
1701
function bigbluebuttonbn_get_recording_type_text($playbacktype) {
1702
    // Check first if string exists, and if it does'nt just default to the capitalised version of the string.
1703
    $text = ucwords($playbacktype);
1704
    $typestringid = 'view_recording_format_' . $playbacktype;
1705
    if (get_string_manager()->string_exists($typestringid, 'bigbluebuttonbn')) {
1706
        $text = get_string($typestringid, 'bigbluebuttonbn');
1707
    }
1708
    return $text;
1709
}
1710
1711
/**
1712
 * Helper function validates a remote resource.
1713
 *
1714
 * @param string $url
1715
 *
1716
 * @return boolean
1717
 */
1718
function bigbluebuttonbn_is_valid_resource($url) {
1719
    $urlhost = parse_url($url, PHP_URL_HOST);
1720
    $serverurlhost = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'), PHP_URL_HOST);
1721
    // Skip validation when the recording URL host is the same as the configured BBB server.
1722
    if ($urlhost == $serverurlhost) {
1723
        return true;
1724
    }
1725
    // Skip validation when the recording URL was already validated.
1726
    $validatedurls = bigbluebuttonbn_cache_get('recordings_cache', 'validated_urls', array());
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a integer|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1727
    if (array_key_exists($urlhost, $validatedurls)) {
1728
        return $validatedurls[$urlhost];
1729
    }
1730
    // Validate the recording URL.
1731
    $validatedurls[$urlhost] = true;
1732
    $curlinfo = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, 'HEAD');
1733
    if (!isset($curlinfo['http_code']) || $curlinfo['http_code'] != 200) {
1734
        $error = "Resources hosted by " . $urlhost . " are unreachable. Server responded with code " . $curlinfo['http_code'];
1735
        debugging($error, DEBUG_DEVELOPER);
1736
        $validatedurls[$urlhost] = false;
1737
    }
1738
    bigbluebuttonbn_cache_set('recordings_cache', 'validated_urls', $validatedurls);
1739
    return $validatedurls[$urlhost];
1740
}
1741
1742
/**
1743
 * Helper function renders the name for meeting used in row for the data used by the recording table.
1744
 *
1745
 * @param array $recording
1746
 * @param array $bbbsession
1747
 *
1748
 * @return string
1749
 */
1750
function bigbluebuttonbn_get_recording_data_row_meeting($recording, $bbbsession) {
0 ignored issues
show
Unused Code introduced by
The parameter $bbbsession is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1751
    $payload = array();
1752
    $source = 'meetingName';
1753
    $metaname = trim($recording['meetingName']);
1754
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $source, $payload);
1755
}
1756
1757
/**
1758
 * Helper function renders the name for recording used in row for the data used by the recording table.
1759
 *
1760
 * @param array $recording
1761
 * @param array $bbbsession
1762
 *
1763
 * @return string
1764
 */
1765
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession) {
1766
    $payload = array();
1767 View Code Duplication
    if (bigbluebuttonbn_get_recording_data_row_editable($bbbsession)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1768
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1769
            'action' => 'edit', 'tag' => 'edit',
1770
            'target' => 'name');
1771
    }
1772
    $oldsource = 'meta_contextactivity';
1773
    if (isset($recording[$oldsource])) {
1774
        $metaname = trim($recording[$oldsource]);
1775
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $oldsource, $payload);
1776
    }
1777
    $newsource = 'meta_bbb-recording-name';
1778 View Code Duplication
    if (isset($recording[$newsource])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1779
        $metaname = trim($recording[$newsource]);
1780
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1781
    }
1782
    $metaname = trim($recording['meetingName']);
1783
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1784
}
1785
1786
/**
1787
 * Helper function renders the description for recording used in row for the data used by the recording table.
1788
 *
1789
 * @param array $recording
1790
 * @param array $bbbsession
1791
 *
1792
 * @return string
1793
 */
1794
function bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession) {
1795
    $payload = array();
1796 View Code Duplication
    if (bigbluebuttonbn_get_recording_data_row_editable($bbbsession)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1797
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1798
            'action' => 'edit', 'tag' => 'edit',
1799
            'target' => 'description');
1800
    }
1801
    $oldsource = 'meta_contextactivitydescription';
1802 View Code Duplication
    if (isset($recording[$oldsource])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1803
        $metadescription = trim($recording[$oldsource]);
1804
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $oldsource, $payload);
1805
    }
1806
    $newsource = 'meta_bbb-recording-description';
1807 View Code Duplication
    if (isset($recording[$newsource])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1808
        $metadescription = trim($recording[$newsource]);
1809
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $newsource, $payload);
1810
    }
1811
    return bigbluebuttonbn_get_recording_data_row_text($recording, '', $newsource, $payload);
1812
}
1813
1814
/**
1815
 * Helper function renders text element for recording used in row for the data used by the recording table.
1816
 *
1817
 * @param array $recording
1818
 * @param string $text
1819
 * @param string $source
1820
 * @param array $data
1821
 *
1822
 * @return string
1823
 */
1824
function bigbluebuttonbn_get_recording_data_row_text($recording, $text, $source, $data) {
1825
    $htmltext = '<span>' . htmlentities($text) . '</span>';
1826
    if (empty($data)) {
1827
        return $htmltext;
1828
    }
1829
    $target = $data['action'] . '-' . $data['target'];
1830
    $id = 'recording-' . $target . '-' . $data['recordingid'];
1831
    $attributes = array('id' => $id, 'class' => 'quickeditlink col-md-20',
1832
        'data-recordingid' => $data['recordingid'], 'data-meetingid' => $data['meetingid'],
1833
        'data-target' => $data['target'], 'data-source' => $source);
1834
    $head = html_writer::start_tag('div', $attributes);
1835
    $tail = html_writer::end_tag('div');
1836
    $payload = array('action' => $data['action'], 'tag' => $data['tag'], 'target' => $data['target']);
1837
    $htmllink = bigbluebuttonbn_actionbar_render_button($recording, $payload);
1838
    return $head . $htmltext . $htmllink . $tail;
1839
}
1840
1841
/**
1842
 * Helper function render a button for the recording action bar
1843
 *
1844
 * @param array $recording
1845
 * @param array $data
1846
 *
1847
 * @return string
1848
 */
1849
function bigbluebuttonbn_actionbar_render_button($recording, $data) {
1850
    global $OUTPUT;
1851
    if (empty($data)) {
1852
        return '';
1853
    }
1854
    $target = $data['action'];
1855
    if (isset($data['target'])) {
1856
        $target .= '-' . $data['target'];
1857
    }
1858
    $id = 'recording-' . $target . '-' . $recording['recordID'];
1859
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recording' . ucfirst($data['action']) . '(this); return false;';
1860
    if ((boolean) \mod_bigbluebuttonbn\locallib\config::get('recording_icons_enabled')) {
1861
        // With icon for $manageaction.
1862
        $iconattributes = array('id' => $id, 'class' => 'iconsmall');
1863
        $linkattributes = array(
1864
            'id' => $id,
1865
            'onclick' => $onclick,
1866
            'data-action' => $data['action'],
1867
        );
1868
        if (!isset($recording['imported'])) {
1869
            $linkattributes['data-links'] = bigbluebuttonbn_count_recording_imported_instances(
1870
                $recording['recordID']
1871
            );
1872
        }
1873
        if (isset($data['disabled'])) {
1874
            $iconattributes['class'] .= ' fa-' . $data['disabled'];
1875
            $linkattributes['class'] = 'disabled';
1876
            unset($linkattributes['onclick']);
1877
        }
1878
        $icon = new pix_icon(
1879
            'i/' . $data['tag'],
1880
            get_string('view_recording_list_actionbar_' . $data['action'], 'bigbluebuttonbn'),
1881
            'moodle',
1882
            $iconattributes
1883
        );
1884
        return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false);
1885
    }
1886
    // With text for $manageaction.
1887
    $linkattributes = array('title' => get_string($data['tag']), 'class' => 'btn btn-xs btn-danger',
1888
        'onclick' => $onclick);
1889
    return $OUTPUT->action_link('#', get_string($data['action']), null, $linkattributes);
1890
}
1891
1892
/**
1893
 * Helper function builds the recording table.
1894
 *
1895
 * @param array $bbbsession
1896
 * @param array $recordings
1897
 * @param array $tools
1898
 *
1899
 * @return object
1900
 */
1901
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1902
    global $DB;
1903
    // Declare the table.
1904
    $table = new html_table();
1905
    $table->data = array();
1906
    // Initialize table headers.
1907
    $table->head[] = get_string('view_recording_playback', 'bigbluebuttonbn');
1908
    $table->head[] = get_string('view_recording_name', 'bigbluebuttonbn');
1909
    $table->head[] = get_string('view_recording_description', 'bigbluebuttonbn');
1910
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1911
        $table->head[] = get_string('view_recording_preview', 'bigbluebuttonbn');
1912
    }
1913
    $table->head[] = get_string('view_recording_date', 'bigbluebuttonbn');
1914
    $table->head[] = get_string('view_recording_duration', 'bigbluebuttonbn');
1915
    $table->align = array('left', 'left', 'left', 'left', 'left', 'center');
1916
    $table->size = array('', '', '', '', '', '');
1917
    if ($bbbsession['managerecordings']) {
1918
        $table->head[] = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1919
        $table->align[] = 'left';
1920
        $table->size[] = (count($tools) * 40) . 'px';
1921
    }
1922
    // Get the groups of the user.
1923
    $usergroups = groups_get_all_groups($bbbsession['course']->id, $bbbsession['userID']);
1924
1925
    // Build table content.
1926
    foreach ($recordings as $recording) {
1927
        $meetingid = $recording['meetingID'];
0 ignored issues
show
Unused Code introduced by
$meetingid is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1928
        $shortmeetingid = explode('-', $recording['meetingID']);
1929
        if (isset($shortmeetingid[0])) {
1930
            $meetingid = $shortmeetingid[0];
0 ignored issues
show
Unused Code introduced by
$meetingid is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1931
        }
1932
        // Check if the record belongs to a Visible Group type.
1933
        list($course, $cm) = get_course_and_cm_from_cmid($bbbsession['cm']->id);
0 ignored issues
show
Unused Code introduced by
The assignment to $course is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
1934
        $groupmode = groups_get_activity_groupmode($cm);
1935
        $displayrow = true;
1936
        if (($groupmode != VISIBLEGROUPS)
1937
                && !$bbbsession['administrator'] && !$bbbsession['moderator']) {
1938
            $groupid = explode('[', $recording['meetingID']);
1939
            if (isset($groupid[1])) {
1940
                // It is a group recording and the user is not moderator/administrator. Recording should not be included by default.
1941
                $displayrow = false;
1942
                $groupid = explode(']', $groupid[1]);
1943
                if (isset($groupid[0])) {
1944
                    foreach ($usergroups as $usergroup) {
1945
                        if ($usergroup->id == $groupid[0]) {
1946
                            // Include recording if the user is in the same group.
1947
                            $displayrow = true;
1948
                        }
1949
                    }
1950
                }
1951
            }
1952
        }
1953
        if ($displayrow) {
1954
            $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1955
            if (!empty($rowdata)) {
1956
                $row = bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata);
1957
                array_push($table->data, $row);
1958
            }
1959
        }
1960
    }
1961
    return $table;
1962
}
1963
1964
/**
1965
 * Helper function builds the recording table row and insert into table.
1966
 *
1967
 * @param array $bbbsession
1968
 * @param array $recording
1969
 * @param object $rowdata
1970
 *
1971
 * @return object
1972
 */
1973
function bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata) {
1974
    $row = new html_table_row();
1975
    $row->id = 'recording-tr-' . $recording['recordID'];
1976
    $row->attributes['data-imported'] = 'false';
1977
    $texthead = '';
1978
    $texttail = '';
1979
    if (isset($recording['imported'])) {
1980
        $row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1981
        $row->attributes['data-imported'] = 'true';
1982
        $texthead = '<em>';
1983
        $texttail = '</em>';
1984
    }
1985
    $rowdata->date_formatted = str_replace(' ', '&nbsp;', $rowdata->date_formatted);
1986
    $row->cells = array();
1987
    $row->cells[] = $texthead . $rowdata->playback . $texttail;
1988
    $row->cells[] = $texthead . $rowdata->recording . $texttail;
1989
    $row->cells[] = $texthead . $rowdata->description . $texttail;
1990
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1991
        $row->cells[] = $rowdata->preview;
1992
    }
1993
    $row->cells[] = $texthead . $rowdata->date_formatted . $texttail;
1994
    $row->cells[] = $rowdata->duration_formatted;
1995
    if ($bbbsession['managerecordings']) {
1996
        $row->cells[] = $rowdata->actionbar;
1997
    }
1998
    return $row;
1999
}
2000
2001
/**
2002
 * Get the basic data to display in the table view
2003
 *
2004
 * @param array $bbbsession the current session
2005
 * @param array $enabledfeatures feature enabled for this activity
2006
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2007
 * non sequential associative array itself that corresponds to the actual recording in BBB
2008
 */
2009
function bigbluebutton_get_recordings_for_table_view($bbbsession, $enabledfeatures) {
2010
    $bigbluebuttonbnid = null;
2011
    if ($enabledfeatures['showroom']) {
2012
        $bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
2013
    }
2014
    // Get recordings.
2015
    $recordings = bigbluebuttonbn_get_recordings(
2016
        $bbbsession['course']->id, $bigbluebuttonbnid, $enabledfeatures['showroom'],
2017
        $bbbsession['bigbluebuttonbn']->recordings_deleted
2018
    );
2019
    if ($enabledfeatures['importrecordings']) {
2020
        // Get recording links.
2021
        $bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
2022
        $recordingsimported = bigbluebuttonbn_get_recordings_imported_array(
2023
            $bbbsession['course']->id, $bigbluebuttonbnid, true
2024
        );
2025
        /* Perform aritmetic addition instead of merge so the imported recordings corresponding to existent
2026
         * recordings are not included. */
2027
        if ($bbbsession['bigbluebuttonbn']->recordings_imported) {
2028
            $recordings = $recordingsimported;
2029
        } else {
2030
            $recordings += $recordingsimported;
2031
        }
2032
    }
2033
    return $recordings;
2034
}
2035
2036
/**
2037
 * Helper function evaluates if recording row should be included in the table.
2038
 *
2039
 * @param array $bbbsession
2040
 * @param array $recording
2041
 *
2042
 * @return boolean
2043
 */
2044
function bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) {
2045
    // Exclude unpublished recordings, only if user has no rights to manage them.
2046
    if ($recording['published'] != 'true' && !$bbbsession['managerecordings']) {
2047
        return false;
2048
    }
2049
    // Imported recordings are always shown as long as they are published.
2050
    if (isset($recording['imported'])) {
2051
        return true;
2052
    }
2053
    // When groups are enabled, exclude those to which the user doesn't have access to.
2054
    if (isset($bbbsession['group']) && $recording['meetingID'] != $bbbsession['meetingid']) {
2055
        return false;
2056
    }
2057
    return true;
2058
}
2059
2060
/**
2061
 * Helper function triggers a send notification when the recording is ready.
2062
 *
2063
 * @param object $bigbluebuttonbn
2064
 *
2065
 * @return void
2066
 */
2067
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) {
2068
    \mod_bigbluebuttonbn\locallib\notifier::notify_recording_ready($bigbluebuttonbn);
2069
}
2070
2071
/**
2072
 * Helper function enqueues list of meeting events to be stored and processed as for completion.
2073
 *
2074
 * @param object $bigbluebuttonbn
2075
 * @param object $jsonobj
2076
 *
2077
 * @return void
2078
 */
2079
function bigbluebuttonbn_process_meeting_events($bigbluebuttonbn, $jsonobj) {
2080
    $meetingid = $jsonobj->{'meeting_id'};
2081
    $recordid = $jsonobj->{'internal_meeting_id'};
2082
    $attendees = $jsonobj->{'data'}->{'attendees'};
2083
    foreach ($attendees as $attendee) {
2084
        $userid = $attendee->{'ext_user_id'};
2085
        $overrides['meetingid'] = $meetingid;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$overrides was never initialized. Although not strictly required by PHP, it is generally a good practice to add $overrides = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2086
        $overrides['userid'] = $userid;
0 ignored issues
show
Bug introduced by
The variable $overrides does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2087
        $meta['recordid'] = $recordid;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$meta was never initialized. Although not strictly required by PHP, it is generally a good practice to add $meta = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2088
        $meta['data'] = $attendee;
2089
        // Stores the log.
2090
        bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTON_LOG_EVENT_SUMMARY, $overrides, json_encode($meta));
2091
        // Enqueue a task for processing the completion.
2092
        bigbluebuttonbn_enqueue_completion_update($bigbluebuttonbn, $userid);
2093
    }
2094
}
2095
2096
/**
2097
 * Helper function enqueues one user for being validated as for completion.
2098
 *
2099
 * @param object $bigbluebuttonbn
2100
 * @param string $userid
2101
 *
2102
 * @return void
2103
 */
2104
function bigbluebuttonbn_enqueue_completion_update($bigbluebuttonbn, $userid) {
2105
    try {
2106
        // Create the instance of completion_update_state task.
2107
        $task = new \mod_bigbluebuttonbn\task\completion_update_state();
2108
        // Add custom data.
2109
        $data = array(
2110
            'bigbluebuttonbn' => $bigbluebuttonbn,
2111
            'userid' => $userid,
2112
        );
2113
        $task->set_custom_data($data);
2114
        // CONTRIB-7457: Task should be executed by a user, maybe Teacher as Student won't have rights for overriding.
2115
        // $ task -> set_userid ( $ user -> id );.
2116
        // Enqueue it.
2117
        \core\task\manager::queue_adhoc_task($task);
2118
    } catch (Exception $e) {
2119
        mtrace("Error while enqueuing completion_update_state task. " . (string) $e);
2120
    }
2121
}
2122
2123
/**
2124
 * Helper function enqueues completion trigger.
2125
 *
2126
 * @param object $bigbluebuttonbn
2127
 * @param string $userid
2128
 *
2129
 * @return void
2130
 */
2131
function bigbluebuttonbn_completion_update_state($bigbluebuttonbn, $userid) {
2132
    global $CFG;
2133
    require_once($CFG->libdir.'/completionlib.php');
2134
    list($course, $cm) = get_course_and_cm_from_instance($bigbluebuttonbn, 'bigbluebuttonbn');
2135
    $completion = new completion_info($course);
2136
    if (!$completion->is_enabled($cm)) {
2137
        mtrace("Completion not enabled");
2138
        return;
2139
    }
2140
    if (!$bigbluebuttonbn->completionattendance) {
2141
        mtrace("Completion by attendance not enabled");
2142
        return;
2143
    }
2144
    if (bigbluebuttonbn_get_completion_state($course, $cm, $userid, COMPLETION_AND)) {
2145
        mtrace("Completion succeeded for user $userid");
2146
        $completion->update_state($cm, COMPLETION_COMPLETE, $userid, true);
2147
    } else {
2148
        mtrace("Completion did not succeed for user $userid");
2149
    }
2150
}
2151
2152
/**
2153
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
2154
 *
2155
 * @return boolean
2156
 */
2157
function bigbluebuttonbn_is_bn_server() {
2158
    if (\mod_bigbluebuttonbn\locallib\config::get('bn_server')) {
2159
        return true;
2160
    }
2161
    $parsedurl = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'));
2162
    if (!isset($parsedurl['host'])) {
2163
        return false;
2164
    }
2165
    $h = $parsedurl['host'];
2166
    $hends = explode('.', $h);
2167
    $hendslength = count($hends);
2168
    return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
2169
}
2170
2171
/**
2172
 * Helper function returns a list of courses a user has access to, wrapped in an array that can be used
2173
 * by a html select.
2174
 *
2175
 * @param array $bbbsession
2176
 *
2177
 * @return array
2178
 */
2179
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) {
2180
    if ($bbbsession['administrator']) {
2181
        $courses = get_courses('all', 'c.fullname ASC');
2182
        // It includes the name of the site as a course (category 0), so remove the first one.
2183
        unset($courses['1']);
2184
    } else {
2185
        $courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname');
2186
    }
2187
    $coursesforselect = [];
2188
    foreach ($courses as $course) {
2189
        $coursesforselect[$course->id] = $course->fullname . " (" . $course->shortname . ")";
2190
    }
2191
    return $coursesforselect;
2192
}
2193
2194
/**
2195
 * Helper function renders recording table.
2196
 *
2197
 * @param array $bbbsession
2198
 * @param array $recordings
2199
 * @param array $tools
2200
 *
2201
 * @return array
2202
 */
2203
function bigbluebuttonbn_output_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
2204
    if (isset($recordings) && !empty($recordings)) {
2205
        // There are recordings for this meeting.
2206
        $table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools);
2207
    }
2208
    if (!isset($table) || !isset($table->data)) {
2209
        // Render a table with "No recordings".
2210
        return html_writer::div(
2211
            get_string('view_message_norecordings', 'bigbluebuttonbn'),
2212
            '',
2213
            array('id' => 'bigbluebuttonbn_recordings_table')
2214
        );
2215
    }
2216
    // Render the table.
2217
    return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_recordings_table'));
2218
}
2219
2220
/**
2221
 * Helper function to convert an html string to plain text.
2222
 *
2223
 * @param string $html
2224
 * @param integer $len
2225
 *
2226
 * @return string
2227
 */
2228
function bigbluebuttonbn_html2text($html, $len = 0) {
2229
    $text = strip_tags($html);
2230
    $text = str_replace('&nbsp;', ' ', $text);
2231
    $textlen = strlen($text);
2232
    $text = mb_substr($text, 0, $len);
2233
    if ($textlen > $len) {
2234
        $text .= '...';
2235
    }
2236
    return $text;
2237
}
2238
2239
/**
2240
 * Helper function to obtain the tags linked to a bigbluebuttonbn activity
2241
 *
2242
 * @param string $id
2243
 *
2244
 * @return string containing the tags separated by commas
2245
 */
2246
function bigbluebuttonbn_get_tags($id) {
2247
    if (class_exists('core_tag_tag')) {
2248
        return implode(',', core_tag_tag::get_item_tags_array('core', 'course_modules', $id));
2249
    }
2250
    return implode(',', tag_get_tags('bigbluebuttonbn', $id));
2251
}
2252
2253
/**
2254
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2255
 * in the getRecordings request
2256
 *
2257
 * @param string $courseid
2258
 * @param string $bigbluebuttonbnid
2259
 * @param bool   $subset
2260
 *
2261
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2262
 */
2263
function bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid = null, $subset = true) {
2264
    if (empty($courseid)) {
2265
        $courseid = 0;
2266
    }
2267
    if (empty($bigbluebuttonbnid)) {
2268
        return "course = '{$courseid}'";
2269
    }
2270
    if ($subset) {
2271
        return "id = '{$bigbluebuttonbnid}'";
2272
    }
2273
    return "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'";
2274
}
2275
2276
/**
2277
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2278
 * in the getRecordings request considering only those that belong to deleted activities.
2279
 *
2280
 * @param string $courseid
2281
 * @param string $bigbluebuttonbnid
2282
 * @param bool   $subset
2283
 *
2284
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2285
 */
2286 View Code Duplication
function bigbluebuttonbn_get_recordings_deleted_sql_select($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2287
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_DELETE . "' AND meta like '%has_recordings%' AND meta like '%true%'";
2288
    if (empty($courseid)) {
2289
        $courseid = 0;
2290
    }
2291
    if (empty($bigbluebuttonbnid)) {
2292
        return $sql . " AND courseid = {$courseid}";
2293
    }
2294
    if ($subset) {
2295
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
2296
    }
2297
    return $sql . " AND courseid = {$courseid} AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
2298
}
2299
2300
/**
2301
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2302
 * in the getRecordings request considering only those that belong to imported recordings.
2303
 *
2304
 * @param string $courseid
2305
 * @param string $bigbluebuttonbnid
2306
 * @param bool   $subset
2307
 *
2308
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2309
 */
2310 View Code Duplication
function bigbluebuttonbn_get_recordings_imported_sql_select($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2311
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
2312
    if (empty($courseid)) {
2313
        $courseid = 0;
2314
    }
2315
    if (empty($bigbluebuttonbnid)) {
2316
        return $sql . " AND courseid = '{$courseid}'";
2317
    }
2318
    if ($subset) {
2319
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
2320
    }
2321
    return $sql . " AND courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
2322
}
2323
2324
/**
2325
 * Helper function to get recordings and imported recordings together.
2326
 *
2327
 * @param string $courseid
2328
 * @param string $bigbluebuttonbnid
2329
 * @param bool   $subset
2330
 * @param bool   $includedeleted
2331
 *
2332
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2333
 * non sequential associative array itself that corresponds to the actual recording in BBB
2334
 */
2335
function bigbluebuttonbn_get_allrecordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
2336
    $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $subset, $includedeleted);
2337
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset);
2338
    return ($recordings + $recordingsimported);
2339
}
2340
2341
/**
2342
 * Helper function to retrieve recordings from the BigBlueButton. The references are stored as events
2343
 * in bigbluebuttonbn_logs.
2344
 *
2345
 * @param string $courseid
2346
 * @param string $bigbluebuttonbnid
2347
 * @param bool   $subset
2348
 * @param bool   $includedeleted
2349
 *
2350
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2351
 * non sequential associative array itself that corresponds to the actual recording in BBB
2352
 */
2353
function bigbluebuttonbn_get_recordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
2354
    global $DB;
2355
    $select = bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid, $subset);
2356
    $bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid');
2357
    /* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in
2358
     * the getRecordings request. */
2359
    if ($includedeleted) {
2360
        $selectdeleted = bigbluebuttonbn_get_recordings_deleted_sql_select($courseid, $bigbluebuttonbnid, $subset);
2361
        $bigbluebuttonbnsdel = $DB->get_records_select_menu(
2362
            'bigbluebuttonbn_logs',
2363
            $selectdeleted,
2364
            null,
2365
            'bigbluebuttonbnid',
2366
            'bigbluebuttonbnid, meetingid'
2367
        );
2368
        if (!empty($bigbluebuttonbnsdel)) {
2369
            // Merge bigbluebuttonbnis from deleted instances, only keys are relevant.
2370
            // Artimetic merge is used in order to keep the keys.
2371
            $bigbluebuttonbns += $bigbluebuttonbnsdel;
2372
        }
2373
    }
2374
    // Gather the meetingids from bigbluebuttonbn logs that include a create with record=true.
2375
    if (empty($bigbluebuttonbns)) {
2376
        return array();
2377
    }
2378
    // Prepare select for loading records based on existent bigbluebuttonbns.
2379
    $sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE ';
2380
    $sql .= '(bigbluebuttonbnid=' . implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)) . ')';
2381
    // Include only Create events and exclude those with record not true.
2382
    $sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?';
2383
    // Execute select for loading records based on existent bigbluebuttonbns.
2384
    $records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%'));
2385
    // Get actual recordings.
2386
    return bigbluebuttonbn_get_recordings_array(array_keys($records));
2387
}
2388
2389
/**
2390
 * Helper function iterates an array with recordings and unset those already imported.
2391
 *
2392
 * @param array $recordings
2393
 * @param integer $courseid
2394
 * @param integer $bigbluebuttonbnid
2395
 *
2396
 * @return array
2397
 */
2398
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) {
2399
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true);
2400
    foreach ($recordings as $key => $recording) {
2401
        if (isset($recordingsimported[$recording['recordID']])) {
2402
            unset($recordings[$key]);
2403
        }
2404
    }
2405
    return $recordings;
2406
}
2407
2408
/**
2409
 * Helper function to count the imported recordings for a recordingid.
2410
 *
2411
 * @param string $recordid
2412
 *
2413
 * @return integer
2414
 */
2415
function bigbluebuttonbn_count_recording_imported_instances($recordid) {
2416
    global $DB;
2417
    $sql = 'SELECT COUNT(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2418
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%"));
2419
}
2420
2421
/**
2422
 * Helper function returns an array with all the instances of imported recordings for a recordingid.
2423
 *
2424
 * @param string $recordid
2425
 *
2426
 * @return array
2427
 */
2428
function bigbluebuttonbn_get_recording_imported_instances($recordid) {
2429
    global $DB;
2430
    $sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2431
    $recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%',
2432
        "%{$recordid}%"));
2433
    return $recordingsimported;
2434
}
2435
2436
/**
2437
 * Helper function to get how much callback events are logged.
2438
 *
2439
 * @param string $recordid
2440
 * @param string $callbacktype
2441
 *
2442
 * @return integer
2443
 */
2444
function bigbluebuttonbn_get_count_callback_event_log($recordid, $callbacktype = 'recording_ready') {
2445
    global $DB;
2446
    $sql = 'SELECT count(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2447
    // Callback type added on version 2.4, validate recording_ready first or assume it on records with no callback.
2448
    if ($callbacktype == 'recording_ready') {
2449
        $sql .= ' AND (meta LIKE ? OR meta NOT LIKE ? )';
2450
        $count = $DB->count_records_sql($sql, array(BIGBLUEBUTTON_LOG_EVENT_CALLBACK, '%recordid%', "%$recordid%",
2451
            $callbacktype, 'callback'));
2452
        return $count;
2453
    }
2454
    $sql .= ' AND meta LIKE ?;';
2455
    $count = $DB->count_records_sql($sql, array(BIGBLUEBUTTON_LOG_EVENT_CALLBACK, '%recordid%', "%$recordid%", "%$callbacktype%"));
2456
    return $count;
2457
}
2458
2459
/**
2460
 * Helper function returns an array with the profiles (with features per profile) for the different types
2461
 * of bigbluebuttonbn instances.
2462
 *
2463
 * @return array
2464
 */
2465
function bigbluebuttonbn_get_instance_type_profiles() {
2466
    $instanceprofiles = array(
2467
        BIGBLUEBUTTONBN_TYPE_ALL => array('id' => BIGBLUEBUTTONBN_TYPE_ALL,
2468
            'name' => get_string('instance_type_default', 'bigbluebuttonbn'),
2469
            'features' => array('all')),
2470
        BIGBLUEBUTTONBN_TYPE_ROOM_ONLY => array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY,
2471
            'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'),
2472
            'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit',
2473
                'recording', 'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups',
2474
                'modstandardelshdr', 'availabilityconditionsheader', 'tagshdr', 'competenciessection',
2475
                'clienttype', 'completionattendance', 'completionengagement', 'availabilityconditionsheader')),
2476
        BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY => array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY,
2477
            'name' => get_string('instance_type_recording_only', 'bigbluebuttonbn'),
2478
            'features' => array('showrecordings', 'importrecordings', 'availabilityconditionsheader')),
2479
    );
2480
    return $instanceprofiles;
2481
}
2482
2483
/**
2484
 * Helper function returns an array with enabled features for an specific profile type.
2485
 *
2486
 * @param array $typeprofiles
2487
 * @param string $type
2488
 *
2489
 * @return array
2490
 */
2491
function bigbluebuttonbn_get_enabled_features($typeprofiles, $type = null) {
2492
    $enabledfeatures = array();
2493
    $features = $typeprofiles[BIGBLUEBUTTONBN_TYPE_ALL]['features'];
2494
    if (!is_null($type) && key_exists($type, $typeprofiles)) {
2495
        $features = $typeprofiles[$type]['features'];
2496
    }
2497
    $enabledfeatures['showroom'] = (in_array('all', $features) || in_array('showroom', $features));
2498
    // Evaluates if recordings are enabled for the Moodle site.
2499
    $enabledfeatures['showrecordings'] = false;
2500
    if (\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
2501
        $enabledfeatures['showrecordings'] = (in_array('all', $features) || in_array('showrecordings', $features));
2502
    }
2503
    $enabledfeatures['importrecordings'] = false;
2504
    if (\mod_bigbluebuttonbn\locallib\config::importrecordings_enabled()) {
2505
        $enabledfeatures['importrecordings'] = (in_array('all', $features) || in_array('importrecordings', $features));
2506
    }
2507
    // Evaluates if clienttype is enabled for the Moodle site.
2508
    $enabledfeatures['clienttype'] = false;
2509
    if (\mod_bigbluebuttonbn\locallib\config::clienttype_enabled()) {
2510
        $enabledfeatures['clienttype'] = (in_array('all', $features) || in_array('clienttype', $features));
2511
    }
2512
    return $enabledfeatures;
2513
}
2514
2515
/**
2516
 * Helper function returns an array with the profiles (with features per profile) for the different types
2517
 * of bigbluebuttonbn instances that the user is allowed to create.
2518
 *
2519
 * @param boolean $room
2520
 * @param boolean $recording
2521
 *
2522
 * @return array
2523
 */
2524
function bigbluebuttonbn_get_instance_type_profiles_create_allowed($room, $recording) {
2525
    $profiles = bigbluebuttonbn_get_instance_type_profiles();
2526
    if (!$room) {
2527
        unset($profiles[BIGBLUEBUTTONBN_TYPE_ROOM_ONLY]);
2528
        unset($profiles[BIGBLUEBUTTONBN_TYPE_ALL]);
2529
    }
2530
    if (!$recording) {
2531
        unset($profiles[BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY]);
2532
        unset($profiles[BIGBLUEBUTTONBN_TYPE_ALL]);
2533
    }
2534
    return $profiles;
2535
}
2536
2537
/**
2538
 * Helper function returns an array with the profiles (with features per profile) for the different types
2539
 * of bigbluebuttonbn instances.
2540
 *
2541
 * @param array $profiles
2542
 *
2543
 * @return array
2544
 */
2545
function bigbluebuttonbn_get_instance_profiles_array($profiles = []) {
2546
    $profilesarray = array();
2547
    foreach ($profiles as $key => $profile) {
2548
        $profilesarray[$profile['id']] = $profile['name'];
2549
    }
2550
    return $profilesarray;
2551
}
2552
2553
/**
2554
 * Helper function returns time in a formatted string.
2555
 *
2556
 * @param integer $time
2557
 *
2558
 * @return string
2559
 */
2560
function bigbluebuttonbn_format_activity_time($time) {
2561
    global $CFG;
2562
    require_once($CFG->dirroot.'/calendar/lib.php');
2563
    $activitytime = '';
2564
    if ($time) {
2565
        $activitytime = calendar_day_representation($time) . ' ' .
2566
        get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn') . ' ' .
2567
        calendar_time_representation($time);
2568
    }
2569
    return $activitytime;
2570
}
2571
2572
/**
2573
 * Helper function returns array with all the strings to be used in javascript.
2574
 *
2575
 * @return array
2576
 */
2577
function bigbluebuttonbn_get_strings_for_js() {
2578
    $locale = bigbluebuttonbn_get_locale();
2579
    $stringman = get_string_manager();
2580
    $strings = $stringman->load_component_strings('bigbluebuttonbn', $locale);
2581
    return $strings;
2582
}
2583
2584
/**
2585
 * Helper function returns the locale set by moodle.
2586
 *
2587
 * @return string
2588
 */
2589
function bigbluebuttonbn_get_locale() {
2590
    $lang = get_string('locale', 'core_langconfig');
2591
    return substr($lang, 0, strpos($lang, '.'));
2592
}
2593
2594
/**
2595
 * Helper function returns the locale code based on the locale set by moodle.
2596
 *
2597
 * @return string
2598
 */
2599
function bigbluebuttonbn_get_localcode() {
2600
    $locale = bigbluebuttonbn_get_locale();
2601
    return substr($locale, 0, strpos($locale, '_'));
2602
}
2603
2604
/**
2605
 * Helper function returns array with the instance settings used in views.
2606
 *
2607
 * @param string $id
2608
 * @param object $bigbluebuttonbnid
2609
 *
2610
 * @return array
2611
 */
2612
function bigbluebuttonbn_view_validator($id, $bigbluebuttonbnid) {
2613
    if ($id) {
2614
        return bigbluebuttonbn_view_instance_id($id);
2615
    }
2616
    if ($bigbluebuttonbnid) {
2617
        return bigbluebuttonbn_view_instance_bigbluebuttonbn($bigbluebuttonbnid);
2618
    }
2619
}
2620
2621
/**
2622
 * Helper function returns array with the instance settings used in views based on id.
2623
 *
2624
 * @param string $id
2625
 *
2626
 * @return array
2627
 */
2628 View Code Duplication
function bigbluebuttonbn_view_instance_id($id) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2629
    global $DB;
2630
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2631
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2632
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2633
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2634
}
2635
2636
/**
2637
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2638
 *
2639
 * @param object $bigbluebuttonbnid
2640
 *
2641
 * @return array
2642
 */
2643 View Code Duplication
function bigbluebuttonbn_view_instance_bigbluebuttonbn($bigbluebuttonbnid) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2644
    global $DB;
2645
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2646
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2647
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2648
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2649
}
2650
2651
/**
2652
 * Helper function renders general settings if the feature is enabled.
2653
 *
2654
 * @param object $renderer
2655
 *
2656
 * @return void
2657
 */
2658
function bigbluebuttonbn_settings_general(&$renderer) {
2659
    // Configuration for BigBlueButton.
2660
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_general_shown()) {
2661
        $renderer->render_group_header('general');
2662
        $renderer->render_group_element(
2663
            'server_url',
2664
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL)
2665
        );
2666
        $renderer->render_group_element(
2667
            'shared_secret',
2668
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET)
2669
        );
2670
    }
2671
}
2672
2673
/**
2674
 * Helper function renders record settings if the feature is enabled.
2675
 *
2676
 * @param object $renderer
2677
 *
2678
 * @return void
2679
 */
2680
function bigbluebuttonbn_settings_record(&$renderer) {
2681
    // Configuration for 'recording' feature.
2682
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_record_meeting_shown()) {
2683
        $renderer->render_group_header('recording');
2684
        $renderer->render_group_element(
2685
            'recording_default',
2686
            $renderer->render_group_element_checkbox('recording_default', 1)
2687
        );
2688
        $renderer->render_group_element(
2689
            'recording_editable',
2690
            $renderer->render_group_element_checkbox('recording_editable', 1)
2691
        );
2692
        $renderer->render_group_element(
2693
            'recording_icons_enabled',
2694
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1)
2695
        );
2696
2697
        // Add recording start to load and allow/hide stop/pause.
2698
        $renderer->render_group_element(
2699
            'recording_all_from_start_default',
2700
            $renderer->render_group_element_checkbox('recording_all_from_start_default', 0)
2701
        );
2702
        $renderer->render_group_element(
2703
            'recording_all_from_start_editable',
2704
            $renderer->render_group_element_checkbox('recording_all_from_start_editable', 0)
2705
        );
2706
        $renderer->render_group_element(
2707
            'recording_hide_button_default',
2708
            $renderer->render_group_element_checkbox('recording_hide_button_default', 0)
2709
        );
2710
        $renderer->render_group_element(
2711
            'recording_hide_button_editable',
2712
            $renderer->render_group_element_checkbox('recording_hide_button_editable', 0)
2713
        );
2714
    }
2715
}
2716
2717
/**
2718
 * Helper function renders import recording settings if the feature is enabled.
2719
 *
2720
 * @param object $renderer
2721
 *
2722
 * @return void
2723
 */
2724 View Code Duplication
function bigbluebuttonbn_settings_importrecordings(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2725
    // Configuration for 'import recordings' feature.
2726
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_import_recordings_shown()) {
2727
        $renderer->render_group_header('importrecordings');
2728
        $renderer->render_group_element(
2729
            'importrecordings_enabled',
2730
            $renderer->render_group_element_checkbox('importrecordings_enabled', 0)
2731
        );
2732
        $renderer->render_group_element(
2733
            'importrecordings_from_deleted_enabled',
2734
            $renderer->render_group_element_checkbox('importrecordings_from_deleted_enabled', 0)
2735
        );
2736
    }
2737
}
2738
2739
/**
2740
 * Helper function renders show recording settings if the feature is enabled.
2741
 *
2742
 * @param object $renderer
2743
 *
2744
 * @return void
2745
 */
2746
function bigbluebuttonbn_settings_showrecordings(&$renderer) {
2747
    // Configuration for 'show recordings' feature.
2748
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_show_recordings_shown()) {
2749
        $renderer->render_group_header('recordings');
2750
        $renderer->render_group_element(
2751
            'recordings_html_default',
2752
            $renderer->render_group_element_checkbox('recordings_html_default', 1)
2753
        );
2754
        $renderer->render_group_element(
2755
            'recordings_html_editable',
2756
            $renderer->render_group_element_checkbox('recordings_html_editable', 0)
2757
        );
2758
        $renderer->render_group_element(
2759
            'recordings_deleted_default',
2760
            $renderer->render_group_element_checkbox('recordings_deleted_default', 1)
2761
        );
2762
        $renderer->render_group_element(
2763
            'recordings_deleted_editable',
2764
            $renderer->render_group_element_checkbox('recordings_deleted_editable', 0)
2765
        );
2766
        $renderer->render_group_element(
2767
            'recordings_imported_default',
2768
            $renderer->render_group_element_checkbox('recordings_imported_default', 0)
2769
        );
2770
        $renderer->render_group_element(
2771
            'recordings_imported_editable',
2772
            $renderer->render_group_element_checkbox('recordings_imported_editable', 1)
2773
        );
2774
        $renderer->render_group_element(
2775
            'recordings_preview_default',
2776
            $renderer->render_group_element_checkbox('recordings_preview_default', 1)
2777
        );
2778
        $renderer->render_group_element(
2779
            'recordings_preview_editable',
2780
            $renderer->render_group_element_checkbox('recordings_preview_editable', 0)
2781
        );
2782
        $renderer->render_group_element(
2783
            'recordings_sortorder',
2784
            $renderer->render_group_element_checkbox('recordings_sortorder', 0)
2785
        );
2786
        $renderer->render_group_element(
2787
            'recordings_validate_url',
2788
            $renderer->render_group_element_checkbox('recordings_validate_url', 1)
2789
        );
2790
    }
2791
}
2792
2793
/**
2794
 * Helper function renders wait for moderator settings if the feature is enabled.
2795
 *
2796
 * @param object $renderer
2797
 *
2798
 * @return void
2799
 */
2800
function bigbluebuttonbn_settings_waitmoderator(&$renderer) {
2801
    // Configuration for wait for moderator feature.
2802
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_wait_moderator_shown()) {
2803
        $renderer->render_group_header('waitformoderator');
2804
        $renderer->render_group_element(
2805
            'waitformoderator_default',
2806
            $renderer->render_group_element_checkbox('waitformoderator_default', 0)
2807
        );
2808
        $renderer->render_group_element(
2809
            'waitformoderator_editable',
2810
            $renderer->render_group_element_checkbox('waitformoderator_editable', 1)
2811
        );
2812
        $renderer->render_group_element(
2813
            'waitformoderator_ping_interval',
2814
            $renderer->render_group_element_text('waitformoderator_ping_interval', 10, PARAM_INT)
2815
        );
2816
        $renderer->render_group_element(
2817
            'waitformoderator_cache_ttl',
2818
            $renderer->render_group_element_text('waitformoderator_cache_ttl', 60, PARAM_INT)
2819
        );
2820
    }
2821
}
2822
2823
/**
2824
 * Helper function renders static voice bridge settings if the feature is enabled.
2825
 *
2826
 * @param object $renderer
2827
 *
2828
 * @return void
2829
 */
2830
function bigbluebuttonbn_settings_voicebridge(&$renderer) {
2831
    // Configuration for "static voice bridge" feature.
2832
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_static_voice_bridge_shown()) {
2833
        $renderer->render_group_header('voicebridge');
2834
        $renderer->render_group_element(
2835
            'voicebridge_editable',
2836
            $renderer->render_group_element_checkbox('voicebridge_editable', 0)
2837
        );
2838
    }
2839
}
2840
2841
/**
2842
 * Helper function renders preuploaded presentation settings if the feature is enabled.
2843
 *
2844
 * @param object $renderer
2845
 *
2846
 * @return void
2847
 */
2848
function bigbluebuttonbn_settings_preupload(&$renderer) {
2849
    // Configuration for "preupload presentation" feature.
2850
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_preupload_presentation_shown()) {
2851
        // This feature only works if curl is installed.
2852
        $preuploaddescripion = get_string('config_preuploadpresentation_description', 'bigbluebuttonbn');
2853
        if (!extension_loaded('curl')) {
2854
            $preuploaddescripion .= '<div class="form-defaultinfo">';
2855
            $preuploaddescripion .= get_string('config_warning_curl_not_installed', 'bigbluebuttonbn');
2856
            $preuploaddescripion .= '</div><br>';
2857
        }
2858
        $renderer->render_group_header('preuploadpresentation', null, $preuploaddescripion);
2859
        if (extension_loaded('curl')) {
2860
            $renderer->render_group_element(
2861
                'preuploadpresentation_enabled',
2862
                $renderer->render_group_element_checkbox('preuploadpresentation_enabled', 0)
2863
            );
2864
        }
2865
    }
2866
}
2867
2868
/**
2869
 * Helper function renders preuploaded presentation manage file if the feature is enabled.
2870
 * This allow to select a file for use as default in all BBB instances if preuploaded presetantion is enable.
2871
 *
2872
 * @param object $renderer
2873
 *
2874
 * @return void
2875
 */
2876
function bigbluebuttonbn_settings_preupload_manage_default_file(&$renderer) {
2877
    // Configuration for "preupload presentation" feature.
2878
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_preupload_presentation_shown()) {
2879
        if (extension_loaded('curl')) {
2880
            // This feature only works if curl is installed.
2881
            $renderer->render_filemanager_default_file_presentation("presentation_default");
2882
        }
2883
    }
2884
}
2885
2886
/**
2887
 * Helper function renders userlimit settings if the feature is enabled.
2888
 *
2889
 * @param object $renderer
2890
 *
2891
 * @return void
2892
 */
2893
function bigbluebuttonbn_settings_userlimit(&$renderer) {
2894
    // Configuration for "user limit" feature.
2895
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_user_limit_shown()) {
2896
        $renderer->render_group_header('userlimit');
2897
        $renderer->render_group_element(
2898
            'userlimit_default',
2899
            $renderer->render_group_element_text('userlimit_default', 0, PARAM_INT)
2900
        );
2901
        $renderer->render_group_element(
2902
            'userlimit_editable',
2903
            $renderer->render_group_element_checkbox('userlimit_editable', 0)
2904
        );
2905
    }
2906
}
2907
2908
/**
2909
 * Helper function renders duration settings if the feature is enabled.
2910
 *
2911
 * @param object $renderer
2912
 *
2913
 * @return void
2914
 */
2915
function bigbluebuttonbn_settings_duration(&$renderer) {
2916
    // Configuration for "scheduled duration" feature.
2917
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_scheduled_duration_shown()) {
2918
        $renderer->render_group_header('scheduled');
2919
        $renderer->render_group_element(
2920
            'scheduled_duration_enabled',
2921
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1)
2922
        );
2923
        $renderer->render_group_element(
2924
            'scheduled_duration_compensation',
2925
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT)
2926
        );
2927
        $renderer->render_group_element(
2928
            'scheduled_pre_opening',
2929
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT)
2930
        );
2931
    }
2932
}
2933
2934
/**
2935
 * Helper function renders participant settings if the feature is enabled.
2936
 *
2937
 * @param object $renderer
2938
 *
2939
 * @return void
2940
 */
2941
function bigbluebuttonbn_settings_participants(&$renderer) {
2942
    // Configuration for defining the default role/user that will be moderator on new activities.
2943
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_moderator_default_shown()) {
2944
        $renderer->render_group_header('participant');
2945
        // UI for 'participants' feature.
2946
        $roles = bigbluebuttonbn_get_roles();
2947
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2948
        $renderer->render_group_element(
2949
            'participant_moderator_default',
2950
            $renderer->render_group_element_configmultiselect(
2951
                'participant_moderator_default',
2952
                array_keys($owner),
2953
                $owner + $roles // CONTRIB-7966: don't use array_merge here so it does not reindex the array.
2954
            )
2955
        );
2956
    }
2957
}
2958
2959
/**
2960
 * Helper function renders notification settings if the feature is enabled.
2961
 *
2962
 * @param object $renderer
2963
 *
2964
 * @return void
2965
 */
2966
function bigbluebuttonbn_settings_notifications(&$renderer) {
2967
    // Configuration for "send notifications" feature.
2968
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_send_notifications_shown()) {
2969
        $renderer->render_group_header('sendnotifications');
2970
        $renderer->render_group_element(
2971
            'sendnotifications_enabled',
2972
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1)
2973
        );
2974
    }
2975
}
2976
2977
/**
2978
 * Helper function renders client type settings if the feature is enabled.
2979
 *
2980
 * @param object $renderer
2981
 *
2982
 * @return void
2983
 */
2984
function bigbluebuttonbn_settings_clienttype(&$renderer) {
2985
    // Configuration for "clienttype" feature.
2986
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_clienttype_shown()) {
2987
        $renderer->render_group_header('clienttype');
2988
        $renderer->render_group_element(
2989
            'clienttype_editable',
2990
            $renderer->render_group_element_checkbox('clienttype_editable', 0)
2991
        );
2992
        // Web Client default.
2993
        $default = intval((int) \mod_bigbluebuttonbn\locallib\config::get('clienttype_default'));
2994
        $choices = array(BIGBLUEBUTTON_CLIENTTYPE_FLASH => get_string('mod_form_block_clienttype_flash', 'bigbluebuttonbn'),
2995
            BIGBLUEBUTTON_CLIENTTYPE_HTML5 => get_string('mod_form_block_clienttype_html5', 'bigbluebuttonbn'));
2996
        $renderer->render_group_element(
2997
            'clienttype_default',
2998
            $renderer->render_group_element_configselect(
2999
                'clienttype_default',
3000
                $default,
3001
                $choices
3002
            )
3003
        );
3004
    }
3005
}
3006
3007
/**
3008
 * Helper function renders general settings if the feature is enabled.
3009
 *
3010
 * @param object $renderer
3011
 *
3012
 * @return void
3013
 */
3014 View Code Duplication
function bigbluebuttonbn_settings_muteonstart(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3015
    // Configuration for BigBlueButton.
3016
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_muteonstart_shown()) {
3017
        $renderer->render_group_header('muteonstart');
3018
        $renderer->render_group_element(
3019
            'muteonstart_default',
3020
            $renderer->render_group_element_checkbox('muteonstart_default', 0)
3021
        );
3022
        $renderer->render_group_element(
3023
            'muteonstart_editable',
3024
            $renderer->render_group_element_checkbox('muteonstart_editable', 0)
3025
        );
3026
    }
3027
}
3028
3029
/**
3030
 * Helper function renders general settings if the feature is enabled.
3031
 *
3032
 * @param object $renderer
3033
 *
3034
 * @return void
3035
 */
3036
function bigbluebuttonbn_settings_locksettings(&$renderer) {
3037
    $renderer->render_group_header('locksettings');
3038
    // Configuration for various lock settings for meetings.
3039
    bigbluebuttonbn_settings_disablecam($renderer);
3040
    bigbluebuttonbn_settings_disablemic($renderer);
3041
    bigbluebuttonbn_settings_disableprivatechat($renderer);
3042
    bigbluebuttonbn_settings_disablepublicchat($renderer);
3043
    bigbluebuttonbn_settings_disablenote($renderer);
3044
    bigbluebuttonbn_settings_hideuserlist($renderer);
3045
    bigbluebuttonbn_settings_lockedlayout($renderer);
3046
    bigbluebuttonbn_settings_lockonjoin($renderer);
3047
    bigbluebuttonbn_settings_lockonjoinconfigurable($renderer);
3048
}
3049
3050
/**
3051
 * Helper function renders general settings if the feature is enabled.
3052
 *
3053
 * @param object $renderer
3054
 *
3055
 * @return void
3056
 */
3057
function bigbluebuttonbn_settings_disablecam(&$renderer) {
3058
    // Configuration for BigBlueButton.
3059
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_disablecam_shown()) {
3060
        $renderer->render_group_element(
3061
            'disablecam_default',
3062
            $renderer->render_group_element_checkbox('disablecam_default', 0)
3063
        );
3064
        $renderer->render_group_element(
3065
            'disablecam_editable',
3066
            $renderer->render_group_element_checkbox('disablecam_editable', 1)
3067
        );
3068
    }
3069
}
3070
3071
/**
3072
 * Helper function renders general settings if the feature is enabled.
3073
 *
3074
 * @param object $renderer
3075
 *
3076
 * @return void
3077
 */
3078
function bigbluebuttonbn_settings_disablemic(&$renderer) {
3079
    // Configuration for BigBlueButton.
3080
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_disablemic_shown()) {
3081
        $renderer->render_group_element(
3082
            'disablemic_default',
3083
            $renderer->render_group_element_checkbox('disablemic_default', 0)
3084
        );
3085
        $renderer->render_group_element(
3086
            'disablecam_editable',
3087
            $renderer->render_group_element_checkbox('disablemic_editable', 1)
3088
        );
3089
    }
3090
}
3091
3092
/**
3093
 * Helper function renders general settings if the feature is enabled.
3094
 *
3095
 * @param object $renderer
3096
 *
3097
 * @return void
3098
 */
3099
function bigbluebuttonbn_settings_disableprivatechat(&$renderer) {
3100
    // Configuration for BigBlueButton.
3101
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_disableprivatechat_shown()) {
3102
        $renderer->render_group_element(
3103
            'disableprivatechat_default',
3104
            $renderer->render_group_element_checkbox('disableprivatechat_default', 0)
3105
        );
3106
        $renderer->render_group_element(
3107
            'disableprivatechat_editable',
3108
            $renderer->render_group_element_checkbox('disableprivatechat_editable', 1)
3109
        );
3110
    }
3111
}
3112
3113
/**
3114
 * Helper function renders general settings if the feature is enabled.
3115
 *
3116
 * @param object $renderer
3117
 *
3118
 * @return void
3119
 */
3120
function bigbluebuttonbn_settings_disablepublicchat(&$renderer) {
3121
    // Configuration for BigBlueButton.
3122
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_disablepublicchat_shown()) {
3123
        $renderer->render_group_element(
3124
            'disablepublicchat_default',
3125
            $renderer->render_group_element_checkbox('disablepublicchat_default', 0)
3126
        );
3127
        $renderer->render_group_element(
3128
            'disablepublicchat_editable',
3129
            $renderer->render_group_element_checkbox('disablepublicchat_editable', 1)
3130
        );
3131
    }
3132
}
3133
3134
/**
3135
 * Helper function renders general settings if the feature is enabled.
3136
 *
3137
 * @param object $renderer
3138
 *
3139
 * @return void
3140
 */
3141
function bigbluebuttonbn_settings_disablenote(&$renderer) {
3142
    // Configuration for BigBlueButton.
3143
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_disablenote_shown()) {
3144
        $renderer->render_group_element(
3145
            'disablenote_default',
3146
            $renderer->render_group_element_checkbox('disablenote_default', 0)
3147
        );
3148
        $renderer->render_group_element(
3149
            'disablenote_editable',
3150
            $renderer->render_group_element_checkbox('disablenote_editable', 1)
3151
        );
3152
    }
3153
}
3154
3155
/**
3156
 * Helper function renders general settings if the feature is enabled.
3157
 *
3158
 * @param object $renderer
3159
 *
3160
 * @return void
3161
 */
3162
function bigbluebuttonbn_settings_hideuserlist(&$renderer) {
3163
    // Configuration for BigBlueButton.
3164
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_hideuserlist_shown()) {
3165
        $renderer->render_group_element(
3166
            'hideuserlist_default',
3167
            $renderer->render_group_element_checkbox('hideuserlist_default', 0)
3168
        );
3169
        $renderer->render_group_element(
3170
            'hideuserlist_editable',
3171
            $renderer->render_group_element_checkbox('hideuserlist_editable', 1)
3172
        );
3173
    }
3174
}
3175
3176
/**
3177
 * Helper function renders general settings if the feature is enabled.
3178
 *
3179
 * @param object $renderer
3180
 *
3181
 * @return void
3182
 */
3183
function bigbluebuttonbn_settings_lockedlayout(&$renderer) {
3184
    // Configuration for BigBlueButton.
3185
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_lockedlayout_shown()) {
3186
        $renderer->render_group_element(
3187
            'lockedlayout_default',
3188
            $renderer->render_group_element_checkbox('lockedlayout_default', 0)
3189
        );
3190
        $renderer->render_group_element(
3191
            'lockedlayout_editable',
3192
            $renderer->render_group_element_checkbox('lockedlayout_editable', 1)
3193
        );
3194
    }
3195
}
3196
3197
/**
3198
 * Helper function renders general settings if the feature is enabled.
3199
 *
3200
 * @param object $renderer
3201
 *
3202
 * @return void
3203
 */
3204
function bigbluebuttonbn_settings_lockonjoin(&$renderer) {
3205
    // Configuration for BigBlueButton.
3206
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_lockonjoin_shown()) {
3207
        $renderer->render_group_element(
3208
            'lockonjoin_default',
3209
            $renderer->render_group_element_checkbox('lockonjoin_default', 0)
3210
        );
3211
        $renderer->render_group_element(
3212
            'lockonjoin_editable',
3213
            $renderer->render_group_element_checkbox('lockonjoin_editable', 1)
3214
        );
3215
    }
3216
}
3217
3218
/**
3219
 * Helper function renders general settings if the feature is enabled.
3220
 *
3221
 * @param object $renderer
3222
 *
3223
 * @return void
3224
 */
3225
function bigbluebuttonbn_settings_lockonjoinconfigurable(&$renderer) {
3226
    // Configuration for BigBlueButton.
3227
    if ((boolean) \mod_bigbluebuttonbn\settings\validator::section_lockonjoinconfigurable_shown()) {
3228
        $renderer->render_group_element(
3229
            'lockonjoinconfigurable_default',
3230
            $renderer->render_group_element_checkbox('lockonjoinconfigurable_default', 0)
3231
        );
3232
        $renderer->render_group_element(
3233
            'lockonjoinconfigurable_editable',
3234
            $renderer->render_group_element_checkbox('lockonjoinconfigurable_editable', 1)
3235
        );
3236
    }
3237
}
3238
3239
/**
3240
 * Helper function renders extended settings if any of the features there is enabled.
3241
 *
3242
 * @param object $renderer
3243
 *
3244
 * @return void
3245
 */
3246 View Code Duplication
function bigbluebuttonbn_settings_extended(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3247
    // Configuration for 'notify users when recording ready' feature.
3248
    if (!(boolean) \mod_bigbluebuttonbn\settings\validator::section_settings_extended_shown()) {
3249
        return;
3250
    }
3251
    $renderer->render_group_header('extended_capabilities');
3252
    // UI for 'notify users when recording ready' feature.
3253
    $renderer->render_group_element(
3254
        'recordingready_enabled',
3255
        $renderer->render_group_element_checkbox('recordingready_enabled', 0)
3256
    );
3257
    // Configuration for extended BN capabilities.
3258
    if (bigbluebuttonbn_is_bn_server()) {
3259
        // UI for 'register meeting events' feature.
3260
        $renderer->render_group_element(
3261
            'meetingevents_enabled',
3262
            $renderer->render_group_element_checkbox('meetingevents_enabled', 0)
3263
        );
3264
    }
3265
}
3266
3267
/**
3268
 * Helper function returns a sha1 encoded string that is unique and will be used as a seed for meetingid.
3269
 *
3270
 * @return string
3271
 */
3272
function bigbluebuttonbn_unique_meetingid_seed() {
3273
    global $DB;
3274
    do {
3275
        $encodedseed = sha1(bigbluebuttonbn_random_password(12));
3276
        $meetingid = (string) $DB->get_field('bigbluebuttonbn', 'meetingid', array('meetingid' => $encodedseed));
3277
    } while ($meetingid == $encodedseed);
3278
    return $encodedseed;
3279
}
3280
3281
/**
3282
 * Helper function renders the link used for recording type in row for the data used by the recording table.
3283
 *
3284
 * @param array $recording
3285
 * @param array $bbbsession
3286
 * @param array $playback
3287
 *
3288
 * @return boolean
3289
 */
3290
function bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback) {
3291
    // All types that are not restricted are included.
3292
    if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'false') {
3293
        return true;
3294
    }
3295
    // All types that are not statistics are included.
3296
    if ($playback['type'] != 'statistics') {
3297
        return true;
3298
    }
3299
    // Exclude imported recordings.
3300
    if (isset($recording['imported'])) {
3301
        return false;
3302
    }
3303
    // Exclude non moderators.
3304
    if (!$bbbsession['administrator'] && !$bbbsession['moderator']) {
3305
        return false;
3306
    }
3307
    return true;
3308
}
3309
3310
/**
3311
 * Renders the general warning message.
3312
 *
3313
 * @param string $message
3314
 * @param string $type
3315
 * @param string $href
3316
 * @param string $text
3317
 * @param string $class
3318
 *
3319
 * @return string
3320
 */
3321
function bigbluebuttonbn_render_warning($message, $type = 'info', $href = '', $text = '', $class = '') {
3322
    global $OUTPUT;
3323
    $output = "\n";
3324
    // Evaluates if config_warning is enabled.
3325
    if (empty($message)) {
3326
        return $output;
3327
    }
3328
    $output .= $OUTPUT->box_start(
3329
        'box boxalignleft adminerror alert alert-' . $type . ' alert-block fade in',
3330
        'bigbluebuttonbn_view_general_warning'
3331
    ) . "\n";
3332
    $output .= '    ' . $message . "\n";
3333
    $output .= '  <div class="singlebutton pull-right">' . "\n";
3334
    if (!empty($href)) {
3335
        $output .= bigbluebuttonbn_render_warning_button($href, $text, $class);
3336
    }
3337
    $output .= '  </div>' . "\n";
3338
    $output .= $OUTPUT->box_end() . "\n";
3339
    return $output;
3340
}
3341
3342
/**
3343
 * Renders the general warning button.
3344
 *
3345
 * @param string $href
3346
 * @param string $text
3347
 * @param string $class
3348
 * @param string $title
3349
 *
3350
 * @return string
3351
 */
3352
function bigbluebuttonbn_render_warning_button($href, $text = '', $class = '', $title = '') {
3353
    if ($text == '') {
3354
        $text = get_string('ok', 'moodle');
3355
    }
3356
    if ($title == '') {
3357
        $title = $text;
3358
    }
3359
    if ($class == '') {
3360
        $class = 'btn btn-secondary';
3361
    }
3362
    $output = '  <form method="post" action="' . $href . '" class="form-inline">' . "\n";
3363
    $output .= '      <button type="submit" class="' . $class . '"' . "\n";
3364
    $output .= '          title="' . $title . '"' . "\n";
3365
    $output .= '          >' . $text . '</button>' . "\n";
3366
    $output .= '  </form>' . "\n";
3367
    return $output;
3368
}
3369
3370
/**
3371
 * Check if a BigBlueButtonBN is available to be used by the current user.
3372
 *
3373
 * @param  stdClass  $bigbluebuttonbn  BigBlueButtonBN instance
3374
 *
3375
 * @return boolean                     status if room available and current user allowed to join
3376
 */
3377
function bigbluebuttonbn_get_availability_status($bigbluebuttonbn) {
3378
    list($roomavailable) = bigbluebuttonbn_room_is_available($bigbluebuttonbn);
3379
    list($usercanjoin) = bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn);
3380
    return ($roomavailable && $usercanjoin);
3381
}
3382
3383
/**
3384
 * Helper for evaluating if scheduled activity is avaiable.
3385
 *
3386
 * @param  stdClass  $bigbluebuttonbn  BigBlueButtonBN instance
3387
 *
3388
 * @return array                       status (room available or not and possible warnings)
3389
 */
3390
function bigbluebuttonbn_room_is_available($bigbluebuttonbn) {
3391
    $open = true;
3392
    $closed = false;
3393
    $warnings = array();
3394
3395
    $timenow = time();
3396
    $timeopen = $bigbluebuttonbn->openingtime;
3397
    $timeclose = $bigbluebuttonbn->closingtime;
3398
    if (!empty($timeopen) && $timeopen > $timenow) {
3399
        $open = false;
3400
    }
3401
    if (!empty($timeclose) && $timenow > $timeclose) {
3402
        $closed = true;
3403
    }
3404
3405
    if (!$open || $closed) {
3406
        if (!$open) {
3407
            $warnings['notopenyet'] = userdate($timeopen);
3408
        }
3409
        if ($closed) {
3410
            $warnings['expired'] = userdate($timeclose);
3411
        }
3412
        return array(false, $warnings);
3413
    }
3414
3415
    return array(true, $warnings);
3416
}
3417
3418
/**
3419
 * Helper for evaluating if meeting can be joined.
3420
 *
3421
 * @param  stdClass $bigbluebuttonbn  BigBlueButtonBN instance
3422
 * @param  string   $mid
3423
 * @param  integer  $userid
3424
 *
3425
 * @return array    status (user allowed to join or not and possible message)
3426
 */
3427
function bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn, $mid = null, $userid = null) {
3428
    // By default, use a meetingid without groups.
3429
    if (empty($mid)) {
3430
        $mid = $bigbluebuttonbn->meetingid . '-' . $bigbluebuttonbn->course . '-' . $bigbluebuttonbn->id;
3431
    }
3432
    // When meeting is running, all authorized users can join right in.
3433
    if (bigbluebuttonbn_is_meeting_running($mid)) {
3434
        return array(true, get_string('view_message_conference_in_progress', 'bigbluebuttonbn'));
3435
    }
3436
    // When meeting is not running, see if the user can join.
3437
    $context = context_course::instance($bigbluebuttonbn->course);
3438
    $participantlist = bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context);
3439
    $isadmin = is_siteadmin($userid);
3440
    $ismoderator = bigbluebuttonbn_is_moderator($context, $participantlist, $userid);
3441
    // If user is administrator, moderator or if is viewer and no waiting is required, join allowed.
3442
    if ($isadmin || $ismoderator || !$bigbluebuttonbn->wait) {
3443
        return array(true, get_string('view_message_conference_room_ready', 'bigbluebuttonbn'));
3444
    }
3445
    // Otherwise, no join allowed.
3446
    return array(false, get_string('view_message_conference_wait_for_moderator', 'bigbluebuttonbn'));
3447
}
3448
3449
/**
3450
 * Helper for getting a value from a bigbluebuttonbn cache.
3451
 *
3452
 * @param  string   $name       BigBlueButtonBN cache
3453
 * @param  string   $key        Key to be retrieved
3454
 * @param  integer  $default    Default value in case key is not found or it is empty
3455
 *
3456
 * @return variable key value
3457
 */
3458
function bigbluebuttonbn_cache_get($name, $key, $default = null) {
3459
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', $name);
3460
    $result = $cache->get($key);
3461
    if (!empty($result)) {
3462
        return $result;
3463
    }
3464
    return $default;
3465
}
3466
3467
/**
3468
 * Helper for setting a value in a bigbluebuttonbn cache.
3469
 *
3470
 * @param  string   $name       BigBlueButtonBN cache
3471
 * @param  string   $key        Key to be created/updated
3472
 * @param  variable $value      Default value to be set
3473
 */
3474
function bigbluebuttonbn_cache_set($name, $key, $value) {
3475
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', $name);
3476
    $cache->set($key, $value);
3477
}
3478
3479
/**
3480
 * Helper for getting the owner userid of a bigbluebuttonbn instance.
3481
 *
3482
 * @param  stdClass $bigbluebuttonbn  BigBlueButtonBN instance
3483
 *
3484
 * @return integer ownerid (a valid user id or null if not registered/found)
3485
 */
3486
function bigbluebuttonbn_instance_ownerid($bigbluebuttonbn) {
3487
    global $DB;
3488
    $filters = array('bigbluebuttonbnid' => $bigbluebuttonbn->id, 'log' => 'Add');
3489
    $ownerid = (integer) $DB->get_field('bigbluebuttonbn_logs', 'userid', $filters);
3490
    return $ownerid;
3491
}
3492
3493
/**
3494
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
3495
 *
3496
 * @return boolean
3497
 */
3498
function bigbluebuttonbn_has_html5_client() {
3499
    $checkurl = \mod_bigbluebuttonbn\locallib\bigbluebutton::root() . "html5client/check";
3500
    $curlinfo = bigbluebuttonbn_wrap_xml_load_file_curl_request($checkurl, 'HEAD');
3501
    return (isset($curlinfo['http_code']) && $curlinfo['http_code'] == 200);
3502
}
3503
3504
/**
3505
 * Setup the bbbsession variable that is used all accross the plugin.
3506
 *
3507
 * @param object $context
3508
 * @param array $bbbsession
3509
 * @return void
3510
 */
3511 View Code Duplication
function bigbluebuttonbn_view_bbbsession_set($context, &$bbbsession) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3512
    global $CFG, $USER;
3513
    // User data.
3514
    $bbbsession['username'] = fullname($USER);
3515
    $bbbsession['userID'] = $USER->id;
3516
    // User roles.
3517
    $bbbsession['administrator'] = is_siteadmin($bbbsession['userID']);
3518
    $participantlist = bigbluebuttonbn_get_participant_list($bbbsession['bigbluebuttonbn'], $context);
3519
    $bbbsession['moderator'] = bigbluebuttonbn_is_moderator($context, $participantlist);
3520
    $bbbsession['managerecordings'] = ($bbbsession['administrator']
3521
        || has_capability('mod/bigbluebuttonbn:managerecordings', $context));
3522
    $bbbsession['importrecordings'] = ($bbbsession['managerecordings']);
3523
    // Server data.
3524
    $bbbsession['modPW'] = $bbbsession['bigbluebuttonbn']->moderatorpass;
3525
    $bbbsession['viewerPW'] = $bbbsession['bigbluebuttonbn']->viewerpass;
3526
    // Database info related to the activity.
3527
    $bbbsession['meetingid'] = $bbbsession['bigbluebuttonbn']->meetingid . '-' . $bbbsession['course']->id . '-' .
3528
    $bbbsession['bigbluebuttonbn']->id;
3529
    $bbbsession['meetingname'] = $bbbsession['bigbluebuttonbn']->name;
3530
    $bbbsession['meetingdescription'] = $bbbsession['bigbluebuttonbn']->intro;
3531
    // Extra data for setting up the Meeting.
3532
    $bbbsession['userlimit'] = intval((int) \mod_bigbluebuttonbn\locallib\config::get('userlimit_default'));
3533
    if ((boolean) \mod_bigbluebuttonbn\locallib\config::get('userlimit_editable')) {
3534
        $bbbsession['userlimit'] = intval($bbbsession['bigbluebuttonbn']->userlimit);
3535
    }
3536
    $bbbsession['voicebridge'] = $bbbsession['bigbluebuttonbn']->voicebridge;
3537
    if ($bbbsession['bigbluebuttonbn']->voicebridge > 0) {
3538
        $bbbsession['voicebridge'] = 70000 + $bbbsession['bigbluebuttonbn']->voicebridge;
3539
    }
3540
    $bbbsession['wait'] = $bbbsession['bigbluebuttonbn']->wait;
3541
    $bbbsession['record'] = $bbbsession['bigbluebuttonbn']->record;
3542
    $bbbsession['recordallfromstart'] = $CFG->bigbluebuttonbn_recording_all_from_start_default;
3543
    if ($CFG->bigbluebuttonbn_recording_all_from_start_editable) {
3544
        $bbbsession['recordallfromstart'] = $bbbsession['bigbluebuttonbn']->recordallfromstart;
3545
    }
3546
3547
    $bbbsession['recordhidebutton'] = $CFG->bigbluebuttonbn_recording_hide_button_default;
3548
    if ($CFG->bigbluebuttonbn_recording_hide_button_editable) {
3549
        $bbbsession['recordhidebutton'] = $bbbsession['bigbluebuttonbn']->recordhidebutton;
3550
    }
3551
3552
    $bbbsession['welcome'] = $bbbsession['bigbluebuttonbn']->welcome;
3553
    if (!isset($bbbsession['welcome']) || $bbbsession['welcome'] == '') {
3554
        $bbbsession['welcome'] = get_string('mod_form_field_welcome_default', 'bigbluebuttonbn');
3555
    }
3556
    if ($bbbsession['bigbluebuttonbn']->record) {
3557
        // Check if is enable record all from start.
3558
        if ($bbbsession['recordallfromstart']) {
3559
            $bbbsession['welcome'] .= '<br><br>' . get_string(
3560
                'bbbrecordallfromstartwarning',
3561
                'bigbluebuttonbn'
3562
            );
3563
        } else {
3564
            $bbbsession['welcome'] .= '<br><br>' . get_string('bbbrecordwarning', 'bigbluebuttonbn');
3565
        }
3566
    }
3567
    $bbbsession['openingtime'] = $bbbsession['bigbluebuttonbn']->openingtime;
3568
    $bbbsession['closingtime'] = $bbbsession['bigbluebuttonbn']->closingtime;
3569
    $bbbsession['muteonstart'] = $bbbsession['bigbluebuttonbn']->muteonstart;
3570
    // Lock settings.
3571
    $bbbsession['disablecam'] = $bbbsession['bigbluebuttonbn']->disablecam;
3572
    $bbbsession['disablemic'] = $bbbsession['bigbluebuttonbn']->disablemic;
3573
    $bbbsession['disableprivatechat'] = $bbbsession['bigbluebuttonbn']->disableprivatechat;
3574
    $bbbsession['disablepublicchat'] = $bbbsession['bigbluebuttonbn']->disablepublicchat;
3575
    $bbbsession['disablenote'] = $bbbsession['bigbluebuttonbn']->disablenote;
3576
    $bbbsession['hideuserlist'] = $bbbsession['bigbluebuttonbn']->hideuserlist;
3577
    $bbbsession['lockedlayout'] = $bbbsession['bigbluebuttonbn']->lockedlayout;
3578
    $bbbsession['lockonjoin'] = $bbbsession['bigbluebuttonbn']->lockonjoin;
3579
    $bbbsession['lockonjoinconfigurable'] = $bbbsession['bigbluebuttonbn']->lockonjoinconfigurable;
3580
    // Additional info related to the course.
3581
    $bbbsession['context'] = $context;
3582
    // Metadata (origin).
3583
    $bbbsession['origin'] = 'Moodle';
3584
    $bbbsession['originVersion'] = $CFG->release;
3585
    $parsedurl = parse_url($CFG->wwwroot);
3586
    $bbbsession['originServerName'] = $parsedurl['host'];
3587
    $bbbsession['originServerUrl'] = $CFG->wwwroot;
3588
    $bbbsession['originServerCommonName'] = '';
3589
    $bbbsession['originTag'] = 'moodle-mod_bigbluebuttonbn (' . get_config('mod_bigbluebuttonbn', 'version') . ')';
3590
    $bbbsession['bnserver'] = bigbluebuttonbn_is_bn_server();
3591
    // Setting for clienttype, assign flash if not enabled, or default if not editable.
3592
    $bbbsession['clienttype'] = BIGBLUEBUTTON_CLIENTTYPE_FLASH;
3593
    if (\mod_bigbluebuttonbn\locallib\config::clienttype_enabled()) {
3594
        $bbbsession['clienttype'] = \mod_bigbluebuttonbn\locallib\config::get('clienttype_default');
3595
    }
3596
    if (\mod_bigbluebuttonbn\locallib\config::get('clienttype_editable') && isset($bbbsession['bigbluebuttonbn']->clienttype)) {
3597
        $bbbsession['clienttype'] = $bbbsession['bigbluebuttonbn']->clienttype;
3598
    }
3599
}
3600
3601
/**
3602
 * Return the status of an activity [open|not_started|ended].
3603
 *
3604
 * @param array $bbbsession
3605
 * @return string
3606
 */
3607 View Code Duplication
function bigbluebuttonbn_view_get_activity_status(&$bbbsession) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3608
    $now = time();
3609
    if (!empty($bbbsession['bigbluebuttonbn']->openingtime) && $now < $bbbsession['bigbluebuttonbn']->openingtime) {
3610
        // The activity has not been opened.
3611
        return 'not_started';
3612
    }
3613
    if (!empty($bbbsession['bigbluebuttonbn']->closingtime) && $now > $bbbsession['bigbluebuttonbn']->closingtime) {
3614
        // The activity has been closed.
3615
        return 'ended';
3616
    }
3617
    // The activity is open.
3618
    return 'open';
3619
}
3620
3621
/**
3622
 * Set session URLs.
3623
 *
3624
 * @param array $bbbsession
3625
 * @param int $id
3626
 * @return string
3627
 */
3628
function bigbluebuttonbn_view_session_config(&$bbbsession, $id) {
3629
    // Operation URLs.
3630
    $bbbsession['bigbluebuttonbnURL'] = plugin::necurl(
3631
        '/mod/bigbluebuttonbn/view.php',
3632
        ['id' => $bbbsession['cm']->id]
3633
    );
3634
    $bbbsession['logoutURL'] = plugin::necurl(
3635
        '/mod/bigbluebuttonbn/bbb_view.php',
3636
        ['action' => 'logout', 'id' => $id, 'bn' => $bbbsession['bigbluebuttonbn']->id]
3637
    );
3638
    $bbbsession['recordingReadyURL'] = plugin::necurl(
3639
        '/mod/bigbluebuttonbn/bbb_broker.php',
3640
        ['action' => 'recording_ready', 'bigbluebuttonbn' => $bbbsession['bigbluebuttonbn']->id]
3641
    );
3642
    $bbbsession['meetingEventsURL'] = plugin::necurl(
3643
        '/mod/bigbluebuttonbn/bbb_broker.php',
3644
        ['action' => 'meeting_events', 'bigbluebuttonbn' => $bbbsession['bigbluebuttonbn']->id]
3645
    );
3646
    $bbbsession['joinURL'] = plugin::necurl(
3647
        '/mod/bigbluebuttonbn/bbb_view.php',
3648
        ['action' => 'join', 'id' => $id, 'bn' => $bbbsession['bigbluebuttonbn']->id]
3649
    );
3650
3651
    // Check status and set extra values.
3652
    $activitystatus = bigbluebuttonbn_view_get_activity_status($bbbsession); // In locallib.
3653 View Code Duplication
    if ($activitystatus == 'ended') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3654
        $bbbsession['presentation'] = bigbluebuttonbn_get_presentation_array(
3655
            $bbbsession['context'],
3656
            $bbbsession['bigbluebuttonbn']->presentation
3657
        );
3658
    } else if ($activitystatus == 'open') {
3659
        $bbbsession['presentation'] = bigbluebuttonbn_get_presentation_array(
3660
            $bbbsession['context'],
3661
            $bbbsession['bigbluebuttonbn']->presentation,
3662
            $bbbsession['bigbluebuttonbn']->id
3663
        );
3664
    }
3665
3666
    return $activitystatus;
3667
}
3668
3669
/**
3670
 * Helper for preparing metadata used while creating the meeting.
3671
 *
3672
 * @param  array    $bbbsession
3673
 * @return array
3674
 */
3675
function bigbluebuttonbn_create_meeting_metadata(&$bbbsession) {
3676
    global $USER;
3677
    // Create standard metadata.
3678
    $metadata = [
3679
        'bbb-origin' => $bbbsession['origin'],
3680
        'bbb-origin-version' => $bbbsession['originVersion'],
3681
        'bbb-origin-server-name' => $bbbsession['originServerName'],
3682
        'bbb-origin-server-common-name' => $bbbsession['originServerCommonName'],
3683
        'bbb-origin-tag' => $bbbsession['originTag'],
3684
        'bbb-context' => $bbbsession['course']->fullname,
3685
        'bbb-context-id' => $bbbsession['course']->id,
3686
        'bbb-context-name' => trim(html_to_text($bbbsession['course']->fullname, 0)),
3687
        'bbb-context-label' => trim(html_to_text($bbbsession['course']->shortname, 0)),
3688
        'bbb-recording-name' => bigbluebuttonbn_html2text($bbbsession['meetingname'], 64),
3689
        'bbb-recording-description' => bigbluebuttonbn_html2text($bbbsession['meetingdescription'], 64),
3690
        'bbb-recording-tags' => bigbluebuttonbn_get_tags($bbbsession['cm']->id), // Same as $id.
3691
    ];
3692
    // Special metadata for recording processing.
3693
    if ((boolean) \mod_bigbluebuttonbn\locallib\config::get('recordingstatus_enabled')) {
3694
        $metadata["bn-recording-status"] = json_encode(
3695
            array(
3696
                'email' => array('"' . fullname($USER) . '" <' . $USER->email . '>'),
3697
                'context' => $bbbsession['bigbluebuttonbnURL'],
3698
            )
3699
        );
3700
    }
3701
    if ((boolean) \mod_bigbluebuttonbn\locallib\config::get('recordingready_enabled')) {
3702
        $metadata['bn-recording-ready-url'] = $bbbsession['recordingReadyURL'];
3703
    }
3704
    if ((boolean) \mod_bigbluebuttonbn\locallib\config::get('meetingevents_enabled')) {
3705
        $metadata['analytics-callback-url'] = $bbbsession['meetingEventsURL'];
3706
    }
3707
    return $metadata;
3708
}
3709