Completed
Push — master ( d8c9ad...1b8539 )
by Jesus
03:11
created

locallib.php ➔ bigbluebuttonbn_view_instance_id()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 7
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 7
loc 7
rs 9.4285
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
defined('MOODLE_INTERNAL') || die;
28
29
global $CFG;
30
31
require_once(dirname(__FILE__).'/lib.php');
32
33
/** @var BIGBLUEBUTTONBN_UPDATE_CACHE boolean set to true indicates that cache has to be updated */
34
const BIGBLUEBUTTONBN_UPDATE_CACHE = true;
35
/** @var BIGBLUEBUTTONBN_TYPE_ALL integer set to 0 defines an instance type that inclueds room and recordings */
36
const BIGBLUEBUTTONBN_TYPE_ALL = 0;
37
/** @var BIGBLUEBUTTONBN_TYPE_ROOM_ONLY integer set to 1 defines an instance type that inclueds only room */
38
const BIGBLUEBUTTONBN_TYPE_ROOM_ONLY = 1;
39
/** @var BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY integer set to 2 defines an instance type that inclueds only recordings */
40
const BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY = 2;
41
/** @var BIGBLUEBUTTONBN_ROLE_VIEWER string defines the bigbluebutton viewer role */
42
const BIGBLUEBUTTONBN_ROLE_VIEWER = 'viewer';
43
/** @var BIGBLUEBUTTONBN_ROLE_MODERATOR string defines the bigbluebutton moderator role */
44
const BIGBLUEBUTTONBN_ROLE_MODERATOR = 'moderator';
45
46
/**
47
 * Register a bigbluebuttonbn event
48
 *
49
 * @param array  $bbbsession
50
 * @param string $event
51
 * @param array  $overrides
52
 * @param string $meta
53
 *
54
 * @return void
55
 */
56
function bigbluebuttonbn_logs(array $bbbsession, $event, array $overrides = [], $meta = null) {
57
    global $DB;
58
    $log = new stdClass();
59
    // Default values.
60
    $log->courseid = $bbbsession['course']->id;
61
    $log->bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
62
    $log->userid = $bbbsession['userID'];
63
    $log->meetingid = $bbbsession['meetingid'];
64
    $log->timecreated = time();
65
    // Overrides.
66
    foreach ($overrides as $key => $value) {
67
        $log->$key = $value;
68
    }
69
    $log->log = $event;
70
    if (isset($meta)) {
71
        $log->meta = $meta;
72
    } else if ($event == BIGBLUEBUTTONBN_LOG_EVENT_CREATE) {
73
        $log->meta = '{"record":'.($bbbsession['record'] ? 'true' : 'false').'}';
74
    }
75
    $DB->insert_record('bigbluebuttonbn_logs', $log);
76
}
77
78
/**
79
 * Builds and retunrs a url for joining a bigbluebutton meeting.
80
 *
81
 * @param string $meetingid
82
 * @param string $username
83
 * @param string $pw
84
 * @param string $logouturl
85
 * @param string $configtoken
86
 * @param string $userid
87
 *
88
 * @return string
89
 */
90
function bigbluebuttonbn_get_join_url($meetingid, $username, $pw, $logouturl, $configtoken = null, $userid = null) {
91
    $data = ['meetingID' => $meetingid,
92
              'fullName' => $username,
93
              'password' => $pw,
94
              'logoutURL' => $logouturl,
95
            ];
96
    if (!is_null($configtoken)) {
97
        $data['configToken'] = $configtoken;
98
    }
99
    if (!is_null($userid)) {
100
        $data['userID'] = $userid;
101
    }
102
    return \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('join', $data);
103
}
104
105
/**
106
 * Creates a bigbluebutton meeting and returns the response in an array.
107
 *
108
 * @param array  $data
109
 * @param array  $metadata
110
 * @param string $pname
111
 * @param string $purl
112
 *
113
 * @return array
114
 */
115
function bigbluebuttonbn_get_create_meeting_array($data, $metadata = array(), $pname = null, $purl = null) {
116
    $createmeetingurl = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('create', $data, $metadata);
117
    $method = 'GET';
118
    $data = null;
119
    if (!is_null($pname) && !is_null($purl)) {
120
        $method = 'POST';
121
        $data = "<?xml version='1.0' encoding='UTF-8'?><modules><module name='presentation'><document url='".
122
            $purl."' /></module></modules>";
123
    }
124
    $xml = bigbluebuttonbn_wrap_xml_load_file($createmeetingurl, $method, $data);
125
    if ($xml) {
126
        $response = array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
127
        if ($xml->meetingID) {
128
            $response += array('meetingID' => $xml->meetingID, 'attendeePW' => $xml->attendeePW,
129
                'moderatorPW' => $xml->moderatorPW, 'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded);
130
        }
131
        return $response;
132
    }
133
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
134
}
135
136
/**
137
 * Fetch meeting info and wrap response in array.
138
 *
139
 * @param string $meetingid
140
 *
141
 * @return array
142
 */
143
function bigbluebuttonbn_get_meeting_info_array($meetingid) {
144
    $xml = bigbluebuttonbn_wrap_xml_load_file(
145
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
146
      );
147
    if ($xml && $xml->returncode == 'SUCCESS' && empty($xml->messageKey)) {
148
        // Meeting info was returned.
149
        return array('returncode' => $xml->returncode,
150
                     'meetingID' => $xml->meetingID,
151
                     'moderatorPW' => $xml->moderatorPW,
152
                     'attendeePW' => $xml->attendeePW,
153
                     'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded,
154
                     'running' => $xml->running,
155
                     'recording' => $xml->recording,
156
                     'startTime' => $xml->startTime,
157
                     'endTime' => $xml->endTime,
158
                     'participantCount' => $xml->participantCount,
159
                     'moderatorCount' => $xml->moderatorCount,
160
                     'attendees' => $xml->attendees,
161
                     'metadata' => $xml->metadata,
162
                   );
163
    }
164
    if ($xml) {
165
        // Either failure or success without meeting info.
166
        return (array)$xml;
167
    }
168
    // If the server is unreachable, then prompts the user of the necessary action.
169
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
170
}
171
172
/**
173
 * Helper function to retrieve recordings from a BigBlueButton server.
174
 *
175
 * @param string|array $meetingids   list of meetingIDs "mid1,mid2,mid3" or array("mid1","mid2","mid3")
176
 * @param string|array $recordingids list of $recordingids "rid1,rid2,rid3" or array("rid1","rid2","rid3") for filtering
177
 *
178
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
179
 */
180
function bigbluebuttonbn_get_recordings_array($meetingids, $recordingids = []) {
181
    $meetingidsarray = $meetingids;
182
    if (!is_array($meetingids)) {
183
        $meetingidsarray = explode(',', $meetingids);
184
    }
185
    // If $meetingidsarray is empty there is no need to go further.
186
    if (empty($meetingidsarray)) {
187
        return array();
188
    }
189
    $recordings = bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray);
0 ignored issues
show
Bug introduced by
It seems like $meetingidsarray defined by $meetingids on line 181 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...
190
    // Sort recordings.
191
    uasort($recordings, 'bigbluebuttonbn_recording_build_sorter');
192
    // Filter recordings based on recordingIDs.
193
    $recordingidsarray = $recordingids;
194
    if (!is_array($recordingids)) {
195
        $recordingidsarray = explode(',', $recordingids);
196
    }
197
    if (empty($recordingidsarray)) {
198
        // No recording ids, no need to filter.
199
        return $recordings;
200
    }
201
    return bigbluebuttonbn_get_recordings_array_filter($recordingidsarray, $recordings);
0 ignored issues
show
Bug introduced by
It seems like $recordingidsarray defined by $recordingids on line 193 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...
202
}
203
204
/**
205
 * Helper function to fetch recordings from a BigBlueButton server.
206
 *
207
 * @param array $meetingidsarray   array with meeting ids in the form array("mid1","mid2","mid3")
208
 *
209
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
210
 */
211
function bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray) {
212
    $recordings = array();
213
    // Execute a paginated getRecordings request.
214
    $pages = floor(count($meetingidsarray) / 25) + 1;
215
    for ($page = 1; $page <= $pages; ++$page) {
216
        $mids = array_slice($meetingidsarray, ($page - 1) * 25, 25);
217
        $recordings += bigbluebuttonbn_get_recordings_array_fetch_page($mids);
218
    }
219
    return $recordings;
220
}
221
222
/**
223
 * Helper function to fetch one page of upto 25 recordings from a BigBlueButton server.
224
 *
225
 * @param array  $mids
226
 *
227
 * @return array
228
 */
229
function bigbluebuttonbn_get_recordings_array_fetch_page($mids) {
230
    $recordings = array();
231
    // Do getRecordings is executed using a method GET (supported by all versions of BBB).
232
    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings', ['meetingID' => implode(',', $mids)]);
233
    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
234
    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
235
        // If there were meetings already created.
236
        foreach ($xml->recordings->recording as $recordingxml) {
237
            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
238
            $recordings[$recording['recordID']] = $recording;
239
        }
240
    }
241
    return $recordings;
242
}
243
244
/**
245
 * Helper function to remove a set of recordings from an array.
246
 *
247
 * @param array  $rids
248
 * @param array  $recordings
249
 *
250
 * @return array
251
 */
252
function bigbluebuttonbn_get_recordings_array_filter($rids, &$recordings) {
253
    foreach ($recordings as $key => $recording) {
254
        if (!in_array($recording['recordID'], $rids)) {
255
            unset($recordings[$key]);
256
        }
257
    }
258
    return $recordings;
259
}
260
261
/**
262
 * Helper function to retrieve imported recordings from the Moodle database.
263
 * The references are stored as events in bigbluebuttonbn_logs.
264
 *
265
 * @param string $courseid
266
 * @param string $bigbluebuttonbnid
267
 * @param bool   $subset
268
 *
269
 * @return associative array with imported recordings indexed by recordID, each recording
270
 * is a non sequential associative array that corresponds to the actual recording in BBB
271
 */
272
function bigbluebuttonbn_get_recordings_imported_array($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
273
    global $DB;
274
    $select = bigbluebuttonbn_get_recordings_imported_sql_select($courseid, $bigbluebuttonbnid, $subset);
275
    $recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select);
276
    $recordsimportedarray = array();
277
    foreach ($recordsimported as $recordimported) {
278
        $meta = json_decode($recordimported->meta, true);
279
        $recording = $meta['recording'];
280
        // Override imported flag with actual ID.
281
        $recording['imported'] = $recordimported->id;
282
        if (isset($recordimported->protected)) {
283
            $recording['protected'] = (string) $recordimported->protected;
284
        }
285
        $recordsimportedarray[$recording['recordID']] = $recording;
286
    }
287
    return $recordsimportedarray;
288
}
289
290
/**
291
 * Helper function to retrive the default config.xml file.
292
 *
293
 * @return string
294
 */
295
function bigbluebuttonbn_get_default_config_xml() {
296
    $xml = bigbluebuttonbn_wrap_xml_load_file(
297
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getDefaultConfigXML')
298
      );
299
    return $xml;
300
}
301
302
/**
303
 * Helper function to convert an xml recording object to an array in the format used by the plugin.
304
 *
305
 * @param object $recording
306
 *
307
 * @return array
308
 */
309
function bigbluebuttonbn_get_recording_array_value($recording) {
310
    // Add formats.
311
    $playbackarray = array();
312
    foreach ($recording->playback->format as $format) {
313
        $playbackarray[(string) $format->type] = array('type' => (string) $format->type,
314
            'url' => trim((string) $format->url), 'length' => (string) $format->length);
315
        // Add preview per format when existing.
316
        if ($format->preview) {
317
            $playbackarray[(string) $format->type]['preview'] = bigbluebuttonbn_get_recording_preview_images($format->preview);
318
        }
319
    }
320
    // Add the metadata to the recordings array.
321
    $metadataarray = bigbluebuttonbn_get_recording_array_meta(get_object_vars($recording->metadata));
322
    $recordingarray = array('recordID' => (string) $recording->recordID,
323
        'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
324
        'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
325
        'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray);
326
    if (isset($recording->protected)) {
327
        $recordingarray['protected'] = (string) $recording->protected;
328
    }
329
    return $recordingarray + $metadataarray;
330
}
331
332
/**
333
 * Helper function to convert an xml recording preview images to an array in the format used by the plugin.
334
 *
335
 * @param object $preview
336
 *
337
 * @return array
338
 */
339
function bigbluebuttonbn_get_recording_preview_images($preview) {
340
    $imagesarray = array();
341
    foreach ($preview->images->image as $image) {
342
        $imagearray = array('url' => trim((string) $image));
343
        foreach ($image->attributes() as $attkey => $attvalue) {
344
            $imagearray[$attkey] = (string) $attvalue;
345
        }
346
        array_push($imagesarray, $imagearray);
347
    }
348
    return $imagesarray;
349
}
350
351
/**
352
 * Helper function to convert an xml recording metadata object to an array in the format used by the plugin.
353
 *
354
 * @param array $metadata
355
 *
356
 * @return array
357
 */
358
function bigbluebuttonbn_get_recording_array_meta($metadata) {
359
    $metadataarray = array();
360
    foreach ($metadata as $key => $value) {
361
        if (is_object($value)) {
362
            $value = '';
363
        }
364
        $metadataarray['meta_'.$key] = $value;
365
    }
366
    return $metadataarray;
367
}
368
369
/**
370
 * Helper function to sort an array of recordings. It compares the startTime in two recording objecs.
371
 *
372
 * @param object $a
373
 * @param object $b
374
 *
375
 * @return array
376
 */
377
function bigbluebuttonbn_recording_build_sorter($a, $b) {
378
    if ($a['startTime'] < $b['startTime']) {
379
        return -1;
380
    }
381
    if ($a['startTime'] == $b['startTime']) {
382
        return 0;
383
    }
384
    return 1;
385
}
386
387
/**
388
 * Perform deleteRecordings on BBB.
389
 *
390
 * @param string $recordids
391
 *
392
 * @return boolean
393
 */
394 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...
395
    $ids = explode(',', $recordids);
396
    foreach ($ids as $id) {
397
        $xml = bigbluebuttonbn_wrap_xml_load_file(
398
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('deleteRecordings', ['recordID' => $id])
399
          );
400
        if ($xml && $xml->returncode != 'SUCCESS') {
401
            return false;
402
        }
403
    }
404
    return true;
405
}
406
407
/**
408
 * Perform publishRecordings on BBB.
409
 *
410
 * @param string $recordids
411
 * @param string $publish
412
 */
413 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...
414
    $ids = explode(',', $recordids);
415
    foreach ($ids as $id) {
416
        $xml = bigbluebuttonbn_wrap_xml_load_file(
417
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish])
418
          );
419
        if ($xml && $xml->returncode != 'SUCCESS') {
420
            return false;
421
        }
422
    }
423
    return true;
424
}
425
426
/**
427
 * Perform updateRecordings on BBB.
428
 *
429
 * @param string $recordids
430
 * @param array $params ['key'=>param_key, 'value']
431
 */
432 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...
433
    $ids = explode(',', $recordids);
434
    foreach ($ids as $id) {
435
        $xml = bigbluebuttonbn_wrap_xml_load_file(
436
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('updateRecordings', ['recordID' => $id] + (array) $params)
437
          );
438
        if ($xml && $xml->returncode != 'SUCCESS') {
439
            return false;
440
        }
441
    }
442
    return true;
443
}
444
445
/**
446
 * Perform end on BBB.
447
 *
448
 * @param string $meetingid
449
 * @param string $modpw
450
 */
451
function bigbluebuttonbn_end_meeting($meetingid, $modpw) {
452
    $xml = bigbluebuttonbn_wrap_xml_load_file(
453
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('end', ['meetingID' => $meetingid, 'password' => $modpw])
454
      );
455
    if ($xml) {
456
        // If the xml packet returned failure it displays the message to the user.
457
        return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
458
    }
459
    // If the server is unreachable, then prompts the user of the necessary action.
460
    return null;
461
}
462
463
/**
464
 * Perform isMeetingRunning on BBB.
465
 *
466
 * @param string $meetingid
467
 */
468
function bigbluebuttonbn_is_meeting_running($meetingid) {
469
    /* As a workaround to isMeetingRunning that always return SUCCESS but only returns true
470
     * when at least one user is in the session, we use getMeetingInfo instead.
471
     */
472
    $xml = bigbluebuttonbn_wrap_xml_load_file(
473
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
474
      );
475
    return ($xml && $xml->returncode == 'SUCCESS');
476
}
477
478
/**
479
 * Perform api request on BBB.
480
 *
481
 * @return string
482
 */
483
function bigbluebuttonbn_get_server_version() {
484
    $xml = bigbluebuttonbn_wrap_xml_load_file(
485
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url()
486
      );
487
    if ($xml && $xml->returncode == 'SUCCESS') {
488
        return $xml->version;
489
    }
490
    return null;
491
}
492
493
/**
494
 * Perform api request on BBB and wraps the response in an XML object
495
 *
496
 * @param string $url
497
 * @param string $method
498
 * @param string $data
499
 * @param string $contenttype
500
 *
501
 * @return object
502
 */
503
function bigbluebuttonbn_wrap_xml_load_file($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
504
    if (extension_loaded('curl')) {
505
        $response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype);
506
        if (!$response) {
507
            debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER);
508
            return null;
509
        }
510
        $previous = libxml_use_internal_errors(true);
511
        try {
512
            $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
513
            return $xml;
514
        } catch (Exception $e) {
515
            libxml_use_internal_errors($previous);
516
            $error = 'Caught exception: '.$e->getMessage();
517
            debugging($error, DEBUG_DEVELOPER);
518
            return null;
519
        }
520
    }
521
    // Alternative request non CURL based.
522
    $previous = libxml_use_internal_errors(true);
523
    try {
524
        $response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
525
        return $response;
526
    } catch (Exception $e) {
527
        $error = 'Caught exception: '.$e->getMessage();
528
        debugging($error, DEBUG_DEVELOPER);
529
        libxml_use_internal_errors($previous);
530
        return null;
531
    }
532
}
533
534
/**
535
 * Perform api request on BBB using CURL and wraps the response in an XML object
536
 *
537
 * @param string $url
538
 * @param string $method
539
 * @param string $data
540
 * @param string $contenttype
541
 *
542
 * @return object
543
 */
544
function bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
545
    $c = new curl();
546
    $c->setopt(array('SSL_VERIFYPEER' => true));
547
    if ($method == 'POST') {
548
        if (is_null($data) || is_array($data)) {
549
            return $c->post($url);
550
        }
551
552
        $options = array();
553
        $options['CURLOPT_HTTPHEADER'] = array(
554
                 'Content-Type: '.$contenttype,
555
                 'Content-Length: '.strlen($data),
556
                 'Content-Language: en-US',
557
               );
558
559
        return $c->post($url, $data, $options);
560
    }
561
    return $c->get($url);
562
}
563
564
/**
565
 * End the session associated with this instance (if it's running).
566
 *
567
 * @param object $bigbluebuttonbn
568
 *
569
 * @return void
570
 */
571
function bigbluebuttonbn_end_meeting_if_running($bigbluebuttonbn) {
572
    $meetingid = $bigbluebuttonbn->meetingid.'-'.$bigbluebuttonbn->course.'-'.$bigbluebuttonbn->id;
573
    if (bigbluebuttonbn_is_meeting_running($meetingid)) {
574
        bigbluebuttonbn_end_meeting($meetingid, $bigbluebuttonbn->moderatorpass);
575
    }
576
}
577
578
/**
579
 * Returns user roles in a context.
580
 *
581
 * @param object $context
582
 * @param integer $userid
583
 *
584
 * @return array $userroles
585
 */
586
function bigbluebuttonbn_get_user_roles($context, $userid) {
587
    global $DB;
588
    $userroles = get_user_roles($context, $userid);
589
    if ($userroles) {
590
        $where = '';
591
        foreach ($userroles as $userrole) {
592
            $where .= (empty($where) ? ' WHERE' : ' OR').' id=' . $userrole->roleid;
593
        }
594
        $userroles = $DB->get_records_sql('SELECT * FROM {role}'.$where);
595
    }
596
    return $userroles;
597
}
598
599
/**
600
 * Returns guest role wrapped in an array.
601
 *
602
 * @return array
603
 */
604
function bigbluebuttonbn_get_guest_role() {
605
    $guestrole = get_guest_role();
606
    return array($guestrole->id => $guestrole);
607
}
608
609
/**
610
 * Returns an array containing all the users in a context.
611
 *
612
 * @param context $context
613
 *
614
 * @return array $users
615
 */
616
function bigbluebuttonbn_get_users(context $context = null) {
617
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
618
    foreach ($users as $key => $value) {
619
        $users[$key] = fullname($value);
620
    }
621
    return $users;
622
}
623
624
/**
625
 * Returns an array containing all the users in a context wrapped for html select element.
626
 *
627
 * @param context $context
628
 *
629
 * @return array $users
630
 */
631
function bigbluebuttonbn_get_users_select(context $context = null) {
632
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
633
    foreach ($users as $key => $value) {
634
        $users[$key] = array('id' => $value->id, 'name' => fullname($value));
635
    }
636
    return $users;
637
}
638
639
/**
640
 * Returns an array containing all the roles in a context.
641
 *
642
 * @param context $context
643
 *
644
 * @return array $roles
645
 */
646
function bigbluebuttonbn_get_roles(context $context = null) {
647
    $roles = (array) role_get_names($context);
648
    foreach ($roles as $key => $value) {
649
        $roles[$key] = $value->localname;
650
    }
651
    return $roles;
652
}
653
654
/**
655
 * Returns an array containing all the roles in a context wrapped for html select element.
656
 *
657
 * @param context $context
658
 *
659
 * @return array $users
660
 */
661
function bigbluebuttonbn_get_roles_select(context $context = null) {
662
    $roles = (array) role_get_names($context);
663
    foreach ($roles as $key => $value) {
664
        $roles[$key] = array('id' => $value->id, 'name' => $value->localname);
665
    }
666
    return $roles;
667
}
668
669
/**
670
 * Returns role that corresponds to an id.
671
 *
672
 * @param string|integer $id
673
 *
674
 * @return object $role
675
 */
676
function bigbluebuttonbn_get_role($id) {
677
    $roles = (array) role_get_names();
678
    if (is_numeric($id)) {
679
        return (object)$roles[$id];
680
    }
681
    foreach ($roles as $role) {
682
        if ($role->shortname == $id) {
683
            return $role;
684
        }
685
    }
686
}
687
688
/**
689
 * Returns an array to populate a list of participants used in mod_form.js.
690
 *
691
 * @param context $context
692
 *
693
 * @return array $data
694
 */
695
function bigbluebuttonbn_get_participant_data($context) {
696
    $data = array(
697
        'all' => array(
698
            'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
699
            'children' => []
700
          )
701
      );
702
    $data['role'] = array(
703
        'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
704
        'children' => bigbluebuttonbn_get_roles_select($context)
705
      );
706
    $data['user'] = array(
707
        'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
708
        'children' => bigbluebuttonbn_get_users_select($context)
709
      );
710
    return $data;
711
}
712
713
/**
714
 * Returns an array to populate a list of participants used in mod_form.php.
715
 *
716
 * @param object $bigbluebuttonbn
717
 * @param context $context
718
 *
719
 * @return array
720
 */
721
function bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context) {
722
    if ($bigbluebuttonbn == null) {
723
        return bigbluebuttonbn_get_participant_list_default($context);
724
    }
725
    return bigbluebuttonbn_get_participant_rules_encoded($bigbluebuttonbn);
726
}
727
728
/**
729
 * Returns an array to populate a list of participants used in mod_form.php with default values.
730
 *
731
 * @param context $context
732
 *
733
 * @return array
734
 */
735
function bigbluebuttonbn_get_participant_list_default($context) {
736
    global $USER;
737
    $participantlistarray = array();
738
    $participantlistarray[] = array(
739
        'selectiontype' => 'all',
740
        'selectionid' => 'all',
741
        'role' => BIGBLUEBUTTONBN_ROLE_VIEWER);
742
    $moderatordefaults = explode(',', \mod_bigbluebuttonbn\locallib\config::get('participant_moderator_default'));
743
    foreach ($moderatordefaults as $moderatordefault) {
744
        if ($moderatordefault == '0') {
745
            if (is_enrolled($context, $USER->id)) {
746
                $participantlistarray[] = array(
747
                    'selectiontype' => 'user',
748
                    'selectionid' => $USER->id,
749
                    'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
750
            }
751
            continue;
752
        }
753
        $participantlistarray[] = array(
754
              'selectiontype' => 'role',
755
              'selectionid' => $moderatordefault,
756
              'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
757
    }
758
    return $participantlistarray;
759
}
760
761
/**
762
 * Returns an array to populate a list of participants used in mod_form.php with bigbluebuttonbn values.
763
 *
764
 * @param object $bigbluebuttonbn
765
 *
766
 * @return array
767
 */
768
function bigbluebuttonbn_get_participant_rules_encoded($bigbluebuttonbn) {
769
    $rules = json_decode($bigbluebuttonbn->participants, true);
770
    if (!is_array($rules)) {
771
        return array();
772
    }
773
    foreach ($rules as $key => $rule) {
774
        if ($rule['selectiontype'] !== 'role' || is_numeric($rule['selectionid'])) {
775
            continue;
776
        }
777
        $role = bigbluebuttonbn_get_role($rule['selectionid']);
778
        if ($role == null) {
779
            unset($rules[$key]);
780
            continue;
781
        }
782
        $rule['selectionid'] = $role->id;
783
        $rules[$key] = $rule;
784
    }
785
    return $rules;
786
}
787
788
/**
789
 * Returns an array to populate a list of participant_selection used in mod_form.php.
790
 *
791
 * @return array
792
 */
793
function bigbluebuttonbn_get_participant_selection_data() {
794
    return [
795
        'type_options' => [
796
            'all' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
797
            'role' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
798
            'user' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
799
          ],
800
        'type_selected' => 'all',
801
        'options' => ['all' => '---------------'],
802
        'selected' => 'all',
803
      ];
804
}
805
806
/**
807
 * Evaluate if a user in a context is moderator based on roles and participation rules.
808
 *
809
 * @param context $context
810
 * @param string $participants
811
 * @param integer $userid
812
 *
813
 * @return boolean
814
 */
815
function bigbluebuttonbn_is_moderator($context, $participants, $userid = null) {
816
    global $USER;
817
    if (empty($participants)) {
818
        // The room that is being used comes from a previous version.
819
        return has_capability('mod/bigbluebuttonbn:moderate', $context);
820
    }
821
    $participantlist = json_decode($participants);
822
    if (!is_array($participantlist)) {
823
        return false;
824
    }
825
    if (empty($userid)) {
826
        $userid = $USER->id;
827
    }
828
    $userroles = bigbluebuttonbn_get_guest_role();
829
    if (!isguestuser()) {
830
        $userroles = bigbluebuttonbn_get_user_roles($context, $userid);
831
    }
832
    return bigbluebuttonbn_is_moderator_validator($participantlist, $userid , $userroles);
833
}
834
835
/**
836
 * Iterates participant list rules to evaluate if a user is moderator.
837
 *
838
 * @param array $participantlist
839
 * @param integer $userid
840
 * @param array $userroles
841
 *
842
 * @return boolean
843
 */
844
function bigbluebuttonbn_is_moderator_validator($participantlist, $userid, $userroles) {
845
    // Iterate participant rules.
846
    foreach ($participantlist as $participant) {
847
        if (bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles)) {
848
            return true;
849
        }
850
    }
851
    return false;
852
}
853
854
/**
855
 * Evaluate if a user is moderator based on roles and a particular participation rule.
856
 *
857
 * @param object $participant
858
 * @param integer $userid
859
 * @param array $userroles
860
 *
861
 * @return boolean
862
 */
863
function bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles) {
864
    if ($participant->role == BIGBLUEBUTTONBN_ROLE_VIEWER) {
865
        return false;
866
    }
867
    // Looks for all configuration.
868
    if ($participant->selectiontype == 'all') {
869
        return true;
870
    }
871
    // Looks for users.
872
    if ($participant->selectiontype == 'user' && $participant->selectionid == $userid) {
873
        return true;
874
    }
875
    // Looks for roles.
876
    $role = bigbluebuttonbn_get_role($participant->selectionid);
877
    if (array_key_exists($role->id, $userroles)) {
878
        return true;
879
    }
880
    return false;
881
}
882
883
/**
884
 * Helper returns error message key for the language file that corresponds to a bigbluebutton error key.
885
 *
886
 * @param string $messagekey
887
 * @param string $defaultkey
888
 *
889
 * @return string
890
 */
891
function bigbluebuttonbn_get_error_key($messagekey, $defaultkey = null) {
892
    if ($messagekey == 'checksumError') {
893
        return 'index_error_checksum';
894
    }
895
    if ($messagekey == 'maxConcurrent') {
896
        return 'view_error_max_concurrent';
897
    }
898
    return $defaultkey;
899
}
900
901
/**
902
 * Helper evaluates if a voicebridge number is unique.
903
 *
904
 * @param integer $instance
905
 * @param integer $voicebridge
906
 *
907
 * @return string
908
 */
909
function bigbluebuttonbn_voicebridge_unique($instance, $voicebridge) {
910
    global $DB;
911
    if ($voicebridge == 0) {
912
        return true;
913
    }
914
    $select = 'voicebridge = ' . $voicebridge;
915
    if ($instance != 0) {
916
        $select .= ' AND id <>' . $instance;
917
    }
918
    if (!$DB->get_records_select('bigbluebuttonbn', $select)) {
919
        return true;
920
    }
921
    return false;
922
}
923
924
/**
925
 * Helper estimate a duration for the meeting based on the closingtime.
926
 *
927
 * @param integer $closingtime
928
 *
929
 * @return integer
930
 */
931
function bigbluebuttonbn_get_duration($closingtime) {
932
    $duration = 0;
933
    $now = time();
934
    if ($closingtime > 0 && $now < $closingtime) {
935
        $duration = ceil(($closingtime - $now) / 60);
936
        $compensationtime = intval((int)\mod_bigbluebuttonbn\locallib\config::get('scheduled_duration_compensation'));
937
        $duration = intval($duration) + $compensationtime;
938
    }
939
    return $duration;
940
}
941
942
/**
943
 * Helper return array containing the file descriptor for a preuploaded presentation.
944
 *
945
 * @param context $context
946
 * @param string $presentation
947
 * @param integer $id
948
 *
949
 * @return array
950
 */
951
function bigbluebuttonbn_get_presentation_array($context, $presentation, $id = null) {
952
    if (empty($presentation)) {
953
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
954
    }
955
    $fs = get_file_storage();
956
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
957
        'itemid, filepath, filename', false);
958
    if (count($files) == 0) {
959
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
960
    }
961
    $file = reset($files);
962
    unset($files);
963
    $pnoncevalue = null;
964
    if (!is_null($id)) {
965
        // Create the nonce component for granting a temporary public access.
966
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn',
967
            'presentation_cache');
968
        $pnoncekey = sha1($id);
969
        /* The item id was adapted for granting public access to the presentation once in order
970
         * to allow BigBlueButton to gather the file. */
971
        $pnoncevalue = bigbluebuttonbn_generate_nonce();
972
        $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
973
    }
974
    $url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
975
        $file->get_filearea(), $pnoncevalue, $file->get_filepath(), $file->get_filename());
976
    return array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
977
            'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file));
978
}
979
980
/**
981
 * Helper generates a nonce used for the preuploaded presentation callback url.
982
 *
983
 * @return string
984
 */
985
function bigbluebuttonbn_generate_nonce() {
986
    $mt = microtime();
987
    $rand = mt_rand();
988
    return md5($mt.$rand);
989
}
990
991
/**
992
 * Helper generates a random password.
993
 *
994
 * @param integer $length
995
 * @param string $unique
996
 *
997
 * @return string
998
 */
999
function bigbluebuttonbn_random_password($length = 8, $unique = "") {
1000
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?';
1001
    do {
1002
        $password = substr(str_shuffle($chars), 0, $length);
1003
    } while ($unique == $password);
1004
    return $password;
1005
}
1006
1007
/**
1008
 * Helper register a bigbluebuttonbn event.
1009
 *
1010
 * @param string $type
1011
 * @param object $bigbluebuttonbn
1012
 * @param array $options [timecreated, userid, other]
1013
 *
1014
 * @return void
1015
 */
1016
function bigbluebuttonbn_event_log($type, $bigbluebuttonbn, $options = []) {
1017
    global $DB;
1018
    if (!in_array($type, \mod_bigbluebuttonbn\event\events::$events)) {
1019
        // No log will be created.
1020
        return;
1021
    }
1022
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
1023
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
1024
    $context = context_module::instance($cm->id);
1025
    $params = array('context' => $context, 'objectid' => $bigbluebuttonbn->id);
1026
    if (array_key_exists('timecreated', $options)) {
1027
        $params['timecreated'] = $options['timecreated'];
1028
    }
1029
    if (array_key_exists('userid', $options)) {
1030
        $params['userid'] = $options['userid'];
1031
    }
1032
    if (array_key_exists('other', $options)) {
1033
        $params['other'] = $options['other'];
1034
    }
1035
    $event = call_user_func_array('\mod_bigbluebuttonbn\event\\' . $type . '::create',
1036
        array($params));
1037
    $event->add_record_snapshot('course_modules', $cm);
1038
    $event->add_record_snapshot('course', $course);
1039
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
1040
    $event->trigger();
1041
}
1042
1043
/**
1044
 * Updates the meeting info cached object when a participant has joined.
1045
 *
1046
 * @param string $meetingid
1047
 * @param bool $ismoderator
1048
 *
1049
 * @return void
1050
 */
1051
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) {
1052
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1053
    $result = $cache->get($meetingid);
1054
    $meetinginfo = json_decode($result['meeting_info']);
1055
    $meetinginfo->participantCount += 1;
1056
    if ($ismoderator) {
1057
        $meetinginfo->moderatorCount += 1;
1058
    }
1059
    $cache->set($meetingid, array('creation_time' => $result['creation_time'],
1060
        'meeting_info' => json_encode($meetinginfo)));
1061
}
1062
1063
/**
1064
 * Gets a meeting info object cached or fetched from the live session.
1065
 *
1066
 * @param string $meetingid
1067
 * @param boolean $updatecache
1068
 *
1069
 * @return array
1070
 */
1071
function bigbluebuttonbn_get_meeting_info($meetingid, $updatecache = false) {
1072
    $cachettl = (int)\mod_bigbluebuttonbn\locallib\config::get('waitformoderator_cache_ttl');
1073
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1074
    $result = $cache->get($meetingid);
1075
    $now = time();
1076
    if (!$updatecache && isset($result) && $now < ($result['creation_time'] + $cachettl)) {
1077
        // Use the value in the cache.
1078
        return (array) json_decode($result['meeting_info']);
1079
    }
1080
    // Ping again and refresh the cache.
1081
    $meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file(
1082
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
1083
      );
1084
    $cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo)));
1085
    return $meetinginfo;
1086
}
1087
1088
/**
1089
 * Publish an imported recording.
1090
 *
1091
 * @param string $id
1092
 * @param boolean $publish
1093
 *
1094
 * @return boolean
1095
 */
1096 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...
1097
    global $DB;
1098
    // Locate the record to be updated.
1099
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1100
    $meta = json_decode($record->meta, true);
1101
    // Prepare data for the update.
1102
    $meta['recording']['published'] = ($publish) ? 'true' : 'false';
1103
    $record->meta = json_encode($meta);
1104
    // Proceed with the update.
1105
    $DB->update_record('bigbluebuttonbn_logs', $record);
1106
    return true;
1107
}
1108
1109
/**
1110
 * Delete an imported recording.
1111
 *
1112
 * @param string $id
1113
 *
1114
 * @return boolean
1115
 */
1116
function bigbluebuttonbn_delete_recording_imported($id) {
1117
    global $DB;
1118
    // Execute delete.
1119
    $DB->delete_records('bigbluebuttonbn_logs', array('id' => $id));
1120
    return true;
1121
}
1122
1123
/**
1124
 * Update an imported recording.
1125
 *
1126
 * @param string $id
1127
 * @param array $params ['key'=>param_key, 'value']
1128
 *
1129
 * @return boolean
1130
 */
1131
function bigbluebuttonbn_update_recording_imported($id, $params) {
1132
    global $DB;
1133
    // Locate the record to be updated.
1134
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1135
    $meta = json_decode($record->meta, true);
1136
    // Prepare data for the update.
1137
    $meta['recording'] = $params + $meta['recording'];
1138
    $record->meta = json_encode($meta);
1139
    // Proceed with the update.
1140
    if (!$DB->update_record('bigbluebuttonbn_logs', $record)) {
1141
        return false;
1142
    }
1143
    return true;
1144
}
1145
1146
/**
1147
 * Protect/Unprotect an imported recording.
1148
 *
1149
 * @param string $id
1150
 * @param boolean $protect
1151
 *
1152
 * @return boolean
1153
 */
1154 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...
1155
    global $DB;
1156
    // Locate the record to be updated.
1157
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1158
    $meta = json_decode($record->meta, true);
1159
    // Prepare data for the update.
1160
    $meta['recording']['protected'] = ($protect) ? 'true' : 'false';
1161
    $record->meta = json_encode($meta);
1162
    // Proceed with the update.
1163
    $DB->update_record('bigbluebuttonbn_logs', $record);
1164
    return true;
1165
}
1166
1167
/**
1168
 * Sets a custom config.xml file for being used on create.
1169
 *
1170
 * @param string $meetingid
1171
 * @param string $configxml
1172
 *
1173
 * @return object
1174
 */
1175
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) {
1176
    $urldefaultconfig = \mod_bigbluebuttonbn\locallib\config::get('server_url').'api/setConfigXML?';
1177
    $configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml);
1178
    $xml = bigbluebuttonbn_wrap_xml_load_file($urldefaultconfig, 'POST',
1179
        $configxmlparams, 'application/x-www-form-urlencoded');
1180
    return $xml;
1181
}
1182
1183
/**
1184
 * Sets qs used with a custom config.xml file request.
1185
 *
1186
 * @param string $meetingid
1187
 * @param string $configxml
1188
 *
1189
 * @return string
1190
 */
1191
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) {
1192
    $params = 'configXML='.urlencode($configxml).'&meetingID='.urlencode($meetingid);
1193
    $configxmlparams = $params.'&checksum='.sha1('setConfigXML'.$params.\mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
1194
    return $configxmlparams;
1195
}
1196
1197
/**
1198
 * Sets a custom config.xml file for being used on create.
1199
 *
1200
 * @param string $meetingid
1201
 * @param string $configxml
1202
 *
1203
 * @return array
1204
 */
1205
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) {
1206
    $configxml = bigbluebuttonbn_setConfigXML($meetingid, $configxml);
1207
    $configxmlarray = (array) $configxml;
1208
    if ($configxmlarray['returncode'] != 'SUCCESS') {
1209
        debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER);
1210
        return '';
1211
    }
1212
    return $configxmlarray['configToken'];
1213
}
1214
1215
/**
1216
 * Helper function builds a row for the data used by the recording table.
1217
 *
1218
 * @param array $bbbsession
1219
 * @param array $recording
1220
 * @param array $tools
1221
 *
1222
 * @return array
1223
 */
1224
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['protect', 'publish', 'delete']) {
1225
    if (!bigbluebuttonbn_include_recording_table_row($bbbsession, $recording)) {
1226
        return;
1227
    }
1228
    $rowdata = new stdClass();
1229
    // Set recording_types.
1230
    $rowdata->recording = bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession);
1231
    // Set activity name.
1232
    $rowdata->activity = bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession);
1233
    // Set activity description.
1234
    $rowdata->description = bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession);
1235
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1236
        // Set recording_preview.
1237
        $rowdata->preview = bigbluebuttonbn_get_recording_data_row_preview($recording);
1238
    }
1239
    // Set date.
1240
    $rowdata->date = bigbluebuttonbn_get_recording_data_row_date($recording);
1241
    // Set formatted date.
1242
    $rowdata->date_formatted = bigbluebuttonbn_get_recording_data_row_date_formatted($rowdata->date);
1243
    // Set formatted duration.
1244
    $rowdata->duration_formatted = $rowdata->duration = bigbluebuttonbn_get_recording_data_row_duration($recording);
1245
    // Set actionbar, if user is allowed to manage recordings.
1246
    if ($bbbsession['managerecordings']) {
1247
        $rowdata->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools);
1248
    }
1249
    return $rowdata;
1250
}
1251
1252
/**
1253
 * Helper function evaluates if a row for the data used by the recording table is editable.
1254
 *
1255
 * @param array $bbbsession
1256
 *
1257
 * @return boolean
1258
 */
1259
function bigbluebuttonbn_get_recording_data_row_editable($bbbsession) {
1260
    return ($bbbsession['managerecordings'] && ((double)$bbbsession['serverversion'] >= 1.0 || $bbbsession['bnserver']));
1261
}
1262
1263
/**
1264
 * Helper function evaluates if recording preview should be included.
1265
 *
1266
 * @param array $bbbsession
1267
 *
1268
 * @return boolean
1269
 */
1270
function bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession) {
1271
    return ((double)$bbbsession['serverversion'] >= 1.0 && $bbbsession['bigbluebuttonbn']->recordings_preview == '1');
1272
}
1273
1274
/**
1275
 * Helper function converts recording date used in row for the data used by the recording table.
1276
 *
1277
 * @param array $recording
1278
 *
1279
 * @return integer
1280
 */
1281
function bigbluebuttonbn_get_recording_data_row_date($recording) {
1282
    if (!isset($recording['startTime'])) {
1283
        return 0;
1284
    }
1285
    return floatval($recording['startTime']);
1286
}
1287
1288
/**
1289
 * Helper function format recording date used in row for the data used by the recording table.
1290
 *
1291
 * @param integer $starttime
1292
 *
1293
 * @return string
1294
 */
1295
function bigbluebuttonbn_get_recording_data_row_date_formatted($starttime) {
1296
    global $USER;
1297
    $starttime = $starttime - ($starttime % 1000);
1298
    // Set formatted date.
1299
    $dateformat = get_string('strftimerecentfull', 'langconfig').' %Z';
1300
    return userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone));
1301
}
1302
1303
/**
1304
 * Helper function converts recording duration used in row for the data used by the recording table.
1305
 *
1306
 * @param array $recording
1307
 *
1308
 * @return integer
1309
 */
1310
function bigbluebuttonbn_get_recording_data_row_duration($recording) {
1311
    $firstplayback = array_values($recording['playbacks'])[0];
1312
    $length = 0;
1313
    if (isset($firstplayback['length'])) {
1314
        $length = $firstplayback['length'];
1315
    }
1316
    return intval($length);
1317
}
1318
1319
/**
1320
 * Helper function builds recording actionbar used in row for the data used by the recording table.
1321
 *
1322
 * @param array $recording
1323
 * @param array $tools
1324
 *
1325
 * @return string
1326
 */
1327
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) {
1328
    $actionbar = '';
1329
    foreach ($tools as $tool) {
1330
        $buttonpayload = bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool);
1331
        if ($tool == 'protect') {
1332
            if (isset($recording['imported'])) {
1333
                $buttonpayload['disabled'] = 'disabled';
1334
            }
1335
            if (!isset($recording['protected'])) {
1336
                $buttonpayload['disabled'] = 'invisible';
1337
            }
1338
        }
1339
        $actionbar .= bigbluebuttonbn_actionbar_render_button($recording, $buttonpayload);
1340
    }
1341
    $head = html_writer::start_tag('div', array(
1342
        'id' => 'recording-actionbar-' . $recording['recordID'],
1343
        'data-recordingid' => $recording['recordID'],
1344
        'data-meetingid' => $recording['meetingID']));
1345
    $tail = html_writer::end_tag('div');
1346
    return $head . $actionbar . $tail;
1347
}
1348
1349
/**
1350
 * Helper function returns the corresponding payload for an actionbar button used in row
1351
 * for the data used by the recording table.
1352
 *
1353
 * @param array $recording
1354
 * @param array $tool
1355
 *
1356
 * @return array
1357
 */
1358
function bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool) {
1359
    if ($tool == 'protect') {
1360
        $protected = 'false';
1361
        if (isset($recording['protected'])) {
1362
            $protected = $recording['protected'];
1363
        }
1364
        return bigbluebuttonbn_get_recording_data_row_action_protect($protected);
1365
    }
1366
    if ($tool == 'publish') {
1367
        return bigbluebuttonbn_get_recording_data_row_action_publish($recording['published']);
1368
    }
1369
    return array('action' => $tool, 'tag' => $tool);
1370
}
1371
1372
/**
1373
 * Helper function returns the payload for protect action button used in row
1374
 * for the data used by the recording table.
1375
 *
1376
 * @param string $protected
1377
 *
1378
 * @return array
1379
 */
1380
function bigbluebuttonbn_get_recording_data_row_action_protect($protected) {
1381
    if ($protected == 'true') {
1382
        return array('action' => 'unprotect', 'tag' => 'lock');
1383
    }
1384
    return array('action' => 'protect', 'tag' => 'unlock');
1385
}
1386
1387
/**
1388
 * Helper function returns the payload for publish action button used in row
1389
 * for the data used by the recording table.
1390
 *
1391
 * @param string $published
1392
 *
1393
 * @return array
1394
 */
1395
function bigbluebuttonbn_get_recording_data_row_action_publish($published) {
1396
    if ($published == 'true') {
1397
        return array('action' => 'unpublish', 'tag' => 'hide');
1398
    }
1399
    return array('action' => 'publish', 'tag' => 'show');
1400
}
1401
1402
/**
1403
 * Helper function builds recording preview used in row for the data used by the recording table.
1404
 *
1405
 * @param array $recording
1406
 *
1407
 * @return string
1408
 */
1409
function bigbluebuttonbn_get_recording_data_row_preview($recording) {
1410
    $options = array('id' => 'preview-'.$recording['recordID'], 'class' => 'container');
1411
    if ($recording['published'] === 'false') {
1412
        $options['hidden'] = 'hidden';
1413
    }
1414
    $recordingpreview = html_writer::start_tag('div', $options);
1415
    foreach ($recording['playbacks'] as $playback) {
1416
        if (isset($playback['preview'])) {
1417
            $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1418
            foreach ($playback['preview'] as $image) {
1419
                $recordingpreview .= html_writer::empty_tag('img',
1420
                    array('src' => trim($image['url']) . '?' . time(), 'class' => 'recording-thumbnail col-sm'));
1421
            }
1422
            $recordingpreview .= html_writer::end_tag('div');
1423
            $recordingpreview .= html_writer::tag('div',
1424
                get_string('view_recording_preview_help', 'bigbluebuttonbn'), array('class' => 'row text-muted small'));
1425
            break;
1426
        }
1427
    }
1428
    $recordingpreview .= html_writer::end_tag('div');
1429
    return $recordingpreview;
1430
}
1431
1432
/**
1433
 * Helper function renders recording types to be used in row for the data used by the recording table.
1434
 *
1435
 * @param array $recording
1436
 * @param array $bbbsession
1437
 *
1438
 * @return string
1439
 */
1440
function bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession) {
1441
    $dataimported = 'false';
1442
    $title = '';
1443
    if (isset($recording['imported'])) {
1444
        $dataimported = 'true';
1445
        $title = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1446
    }
1447
    $visibility = '';
1448
    if ($recording['published'] === 'false') {
1449
        $visibility = 'hidden ';
1450
    }
1451
    $id = 'playbacks-'.$recording['recordID'];
1452
    $recordingtypes = html_writer::start_tag('div', array('id' => $id, 'data-imported' => $dataimported,
1453
          'data-meetingid' => $recording['meetingID'], 'data-recordingid' => $recording['recordID'],
1454
          'title' => $title, $visibility => $visibility));
1455
    foreach ($recording['playbacks'] as $playback) {
1456
        $recordingtypes .= bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback);
1457
    }
1458
    $recordingtypes .= html_writer::end_tag('div');
1459
    return $recordingtypes;
1460
}
1461
1462
/**
1463
 * Helper function renders the link used for recording type in row for the data used by the recording table.
1464
 *
1465
 * @param array $recording
1466
 * @param array $bbbsession
1467
 * @param array $playback
1468
 *
1469
 * @return string
1470
 */
1471
function bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback) {
1472
    global $CFG, $OUTPUT;
1473
    if (!bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback)) {
1474
        return '';
1475
    }
1476
    $title = get_string('view_recording_format_'.$playback['type'], 'bigbluebuttonbn');
1477
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recordingPlay(this);';
1478
    $href = $CFG->wwwroot . '/mod/bigbluebuttonbn/bbb_view.php?action=play&bn=' . $bbbsession['bigbluebuttonbn']->id .
1479
      '&mid='.$recording['meetingID'] . '&rid=' . $recording['recordID'] . '&rtype=' . $playback['type'];
1480
    if (!isset($recording['imported']) || !isset($recording['protected']) || $recording['protected'] === 'false') {
1481
        $href .= '&href='.urlencode(trim($playback['url']));
1482
    }
1483
    $id = 'recording-play-' . $playback['type'] . '-' . $recording['recordID'];
1484
    $linkattributes = array(
1485
        'id' => $id,
1486
        'onclick' => $onclick,
1487
        'data-action' => 'play',
1488
        'data-target' => $playback['type'],
1489
        'data-href' => $href,
1490
        'class' => 'btn btn-sm btn-default'
1491
      );
1492
    return $OUTPUT->action_link('#', $title, null, $linkattributes) . '&#32;';
1493
}
1494
1495
/**
1496
 * Helper function renders the name for recording used in row for the data used by the recording table.
1497
 *
1498
 * @param array $recording
1499
 * @param array $bbbsession
1500
 *
1501
 * @return string
1502
 */
1503
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession) {
1504
    $payload = array();
1505 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...
1506
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1507
            'action' => 'edit', 'tag' => 'edit',
1508
            'target' => 'name');
1509
    }
1510
    $oldsource = 'meta_contextactivity';
1511
    if (isset($recording[$oldsource])) {
1512
        $metaname = trim($recording[$oldsource]);
1513
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $oldsource, $payload);
1514
    }
1515
    $newsource = 'meta_bbb-recording-name';
1516 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...
1517
        $metaname = trim($recording[$newsource]);
1518
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1519
    }
1520
    $metaname = trim($recording['meetingName']);
1521
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1522
}
1523
1524
/**
1525
 * Helper function renders the description for recording used in row for the data used by the recording table.
1526
 *
1527
 * @param array $recording
1528
 * @param array $bbbsession
1529
 *
1530
 * @return string
1531
 */
1532
function bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession) {
1533
    $payload = array();
1534 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...
1535
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1536
            'action' => 'edit', 'tag' => 'edit',
1537
            'target' => 'description');
1538
    }
1539
    $oldsource = 'meta_contextactivitydescription';
1540 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...
1541
        $metadescription = trim($recording[$oldsource]);
1542
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $oldsource, $payload);
1543
    }
1544
    $newsource = 'meta_bbb-recording-description';
1545 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...
1546
        $metadescription = trim($recording[$newsource]);
1547
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $newsource, $payload);
1548
    }
1549
    return bigbluebuttonbn_get_recording_data_row_text($recording, '', $newsource, $payload);
1550
}
1551
1552
/**
1553
 * Helper function renders text element for recording used in row for the data used by the recording table.
1554
 *
1555
 * @param array $recording
1556
 * @param string $text
1557
 * @param string $source
1558
 * @param array $data
1559
 *
1560
 * @return string
1561
 */
1562
function bigbluebuttonbn_get_recording_data_row_text($recording, $text, $source, $data) {
1563
    $htmltext = '<span>' . htmlentities($text) . '</span>';
1564
    if (empty($data)) {
1565
        return $htmltext;
1566
    }
1567
    $target = $data['action'] . '-' . $data['target'];
1568
    $id = 'recording-' . $target . '-' . $data['recordingid'];
1569
    $attributes = array('id' => $id, 'class' => 'quickeditlink col-md-20',
1570
        'data-recordingid' => $data['recordingid'], 'data-meetingid' => $data['meetingid'],
1571
        'data-target' => $data['target'], 'data-source' => $source);
1572
    $head = html_writer::start_tag('div', $attributes);
1573
    $tail = html_writer::end_tag('div');
1574
    $payload = array('action' => $data['action'], 'tag' => $data['tag'], 'target' => $data['target']);
1575
    $htmllink = bigbluebuttonbn_actionbar_render_button($recording, $payload);
1576
    return $head . $htmltext . $htmllink . $tail;
1577
}
1578
1579
/**
1580
 * Helper function render a button for the recording action bar
1581
 *
1582
 * @param array $recording
1583
 * @param array $data
1584
 *
1585
 * @return string
1586
 */
1587
function bigbluebuttonbn_actionbar_render_button($recording, $data) {
1588
    global $OUTPUT;
1589
    if (empty($data)) {
1590
        return '';
1591
    }
1592
    $target = $data['action'];
1593
    if (isset($data['target'])) {
1594
        $target .= '-' . $data['target'];
1595
    }
1596
    $id = 'recording-' . $target . '-' . $recording['recordID'];
1597
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recording' . ucfirst($data['action']) . '(this);';
1598
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::get('recording_icons_enabled')) {
1599
        // With icon for $manageaction.
1600
        $iconattributes = array('id' => $id, 'class' => 'iconsmall');
1601
        $linkattributes = array(
1602
            'id' => $id,
1603
            'onclick' => $onclick,
1604
            'data-action' => $data['action']
1605
          );
1606
        if (!isset($recording['imported'])) {
1607
            $linkattributes['data-links'] = bigbluebuttonbn_count_recording_imported_instances(
1608
              $recording['recordID']);
1609
        }
1610
        if (isset($data['disabled'])) {
1611
            $iconattributes['class'] .= ' fa-' . $data['disabled'];
1612
            $linkattributes['class'] = 'disabled';
1613
            unset($linkattributes['onclick']);
1614
        }
1615
        $icon = new pix_icon('i/'.$data['tag'],
1616
            get_string('view_recording_list_actionbar_' . $data['action'], 'bigbluebuttonbn'),
1617
            'moodle', $iconattributes);
1618
        return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false);
1619
    }
1620
    // With text for $manageaction.
1621
    $linkattributes = array('title' => get_string($data['tag']), 'class' => 'btn btn-xs btn-danger',
1622
        'onclick' => $onclick);
1623
    return $OUTPUT->action_link('#', get_string($data['action']), null, $linkattributes);
1624
}
1625
1626
/**
1627
 * Helper function builds the data used for headers by the recording table.
1628
 *
1629
 * @param array $bbbsession
1630
 *
1631
 * @return array
1632
 */
1633
function bigbluebuttonbn_get_recording_columns($bbbsession) {
1634
    $columns = array();
1635
    // Initialize table headers.
1636
    $columns[] = array('key' => 'recording', 'label' => get_string('view_recording_recording', 'bigbluebuttonbn'),
1637
        'width' => '125px', 'allowHTML' => true);
1638
    $columns[] = array('key' => 'activity', 'label' => get_string('view_recording_activity', 'bigbluebuttonbn'),
1639
        'sortable' => true, 'width' => '175px', 'allowHTML' => true);
1640
    $columns[] = array('key' => 'description', 'label' => get_string('view_recording_description', 'bigbluebuttonbn'),
1641
        'sortable' => true, 'width' => '250px', 'allowHTML' => true);
1642
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1643
        $columns[] = array('key' => 'preview', 'label' => get_string('view_recording_preview', 'bigbluebuttonbn'),
1644
            'width' => '250px', 'allowHTML' => true);
1645
    }
1646
    $columns[] = array('key' => 'date', 'label' => get_string('view_recording_date', 'bigbluebuttonbn'),
1647
        'sortable' => true, 'width' => '225px', 'allowHTML' => true);
1648
    $columns[] = array('key' => 'duration', 'label' => get_string('view_recording_duration', 'bigbluebuttonbn'),
1649
        'width' => '50px');
1650
    if ($bbbsession['managerecordings']) {
1651
        $columns[] = array('key' => 'actionbar', 'label' => get_string('view_recording_actionbar', 'bigbluebuttonbn'),
1652
            'width' => '120px', 'allowHTML' => true);
1653
    }
1654
    return $columns;
1655
}
1656
1657
/**
1658
 * Helper function builds the data used by the recording table.
1659
 *
1660
 * @param array $bbbsession
1661
 * @param array $recordings
1662
 * @param array $tools
1663
 *
1664
 * @return array
1665
 */
1666
function bigbluebuttonbn_get_recording_data($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1667
    $tabledata = array();
1668
    // Build table content.
1669
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
1670
        // There are recordings for this meeting.
1671
        foreach ($recordings as $recording) {
1672
            $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1673
            if (!empty($rowdata)) {
1674
                array_push($tabledata, $rowdata);
1675
            }
1676
        }
1677
    }
1678
    return $tabledata;
1679
}
1680
1681
/**
1682
 * Helper function builds the recording table.
1683
 *
1684
 * @param array $bbbsession
1685
 * @param array $recordings
1686
 * @param array $tools
1687
 *
1688
 * @return object
1689
 */
1690
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1691
    // Declare the table.
1692
    $table = new html_table();
1693
    $table->data = array();
1694
    // Initialize table headers.
1695
    $table->head[] = get_string('view_recording_playback', 'bigbluebuttonbn');
1696
    $table->head[] = get_string('view_recording_recording', 'bigbluebuttonbn');
1697
    $table->head[] = get_string('view_recording_description', 'bigbluebuttonbn');
1698
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1699
        $table->head[] = get_string('view_recording_preview', 'bigbluebuttonbn');
1700
    }
1701
    $table->head[] = get_string('view_recording_date', 'bigbluebuttonbn');
1702
    $table->head[] = get_string('view_recording_duration', 'bigbluebuttonbn');
1703
    $table->align = array('left', 'left', 'left', 'left', 'left', 'center');
1704
    $table->size = array('', '', '', '', '', '');
1705
    if ($bbbsession['managerecordings']) {
1706
        $table->head[] = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1707
        $table->align[] = 'left';
1708
        $table->size[] = (count($tools) * 40) . 'px';
1709
    }
1710
    // Build table content.
1711
    foreach ($recordings as $recording) {
1712
        $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1713
        if (!empty($rowdata)) {
1714
            $row = bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata);
1715
            array_push($table->data, $row);
1716
        }
1717
    }
1718
    return $table;
1719
}
1720
1721
/**
1722
 * Helper function builds the recording table row and insert into table.
1723
 *
1724
 * @param array $bbbsession
1725
 * @param array $recording
1726
 * @param object $rowdata
1727
 *
1728
 * @return object
1729
 */
1730
function bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata) {
1731
    $row = new html_table_row();
1732
    $row->id = 'recording-td-'.$recording['recordID'];
1733
    $row->attributes['data-imported'] = 'false';
1734
    $texthead = '';
1735
    $texttail = '';
1736
    if (isset($recording['imported'])) {
1737
        $row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1738
        $row->attributes['data-imported'] = 'true';
1739
        $texthead = '<em>';
1740
        $texttail = '</em>';
1741
    }
1742
    $rowdata->date_formatted = str_replace(' ', '&nbsp;', $rowdata->date_formatted);
1743
    $row->cells = array();
1744
    $row->cells[] = $texthead . $rowdata->recording . $texttail;
1745
    $row->cells[] = $texthead . $rowdata->activity . $texttail;
1746
    $row->cells[] = $texthead . $rowdata->description . $texttail;
1747
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1748
        $row->cells[] = $rowdata->preview;
1749
    }
1750
    $row->cells[] = $texthead . $rowdata->date_formatted . $texttail;
1751
    $row->cells[] = $rowdata->duration_formatted;
1752
    if ($bbbsession['managerecordings']) {
1753
        $row->cells[] = $rowdata->actionbar;
1754
    }
1755
    return $row;
1756
}
1757
1758
/**
1759
 * Helper function evaluates if recording row should be included in the table.
1760
 *
1761
 * @param array $bbbsession
1762
 * @param array $recording
1763
 *
1764
 * @return boolean
1765
 */
1766
function bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) {
1767
    // Exclude unpublished recordings, only if user has no rights to manage them.
1768
    if ($recording['published'] != 'true' && !$bbbsession['managerecordings']) {
1769
        return false;
1770
    }
1771
    // Imported recordings are always shown as long as they are published.
1772
    if (isset($recording['imported'])) {
1773
        return true;
1774
    }
1775
    // When groups are enabled, exclude those to which the user doesn't have access to.
1776
    if (isset($bbbsession['group']) && $recording['meetingID'] != $bbbsession['meetingid']) {
1777
        return false;
1778
    }
1779
    return true;
1780
}
1781
1782
/**
1783
 * Helper function triggers a send notification when the recording is ready.
1784
 *
1785
 * @param object $bigbluebuttonbn
1786
 *
1787
 * @return void
1788
 */
1789
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) {
1790
    $sender = get_admin();
1791
    // Prepare message.
1792
    $messagetext = '<p>'.get_string('email_body_recording_ready_for', 'bigbluebuttonbn').
1793
        ' &quot;' . $bigbluebuttonbn->name . '&quot; '.
1794
        get_string('email_body_recording_ready_is_ready', 'bigbluebuttonbn').'.</p>';
1795
    $context = context_course::instance($bigbluebuttonbn->course);
1796
    \mod_bigbluebuttonbn\locallib\notifier::notification_send($context, $sender, $bigbluebuttonbn, $messagetext);
1797
}
1798
1799
/**
1800
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
1801
 *
1802
 * @return boolean
1803
 */
1804
function bigbluebuttonbn_is_bn_server() {
1805
    $parsedurl = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'));
1806
    if (!isset($parsedurl['host'])) {
1807
        return false;
1808
    }
1809
    $h = $parsedurl['host'];
1810
    $hends = explode('.', $h);
1811
    $hendslength = count($hends);
1812
    return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
1813
}
1814
1815
/**
1816
 * Helper function returns a list of courses a user has access to, wrapped in an array that can be used
1817
 * by a html select.
1818
 *
1819
 * @param array $bbbsession
1820
 *
1821
 * @return array
1822
 */
1823
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) {
1824
    if ($bbbsession['administrator']) {
1825
        $courses = get_courses('all', 'c.fullname ASC', 'c.id,c.shortname,c.fullname');
1826
        // It includes the name of the site as a course (category 0), so remove the first one.
1827
        unset($courses['1']);
1828
    } else {
1829
        $courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname');
1830
    }
1831
    $coursesforselect = [];
1832
    foreach ($courses as $course) {
1833
        $coursesforselect[$course->id] = $course->fullname;
1834
    }
1835
    return $coursesforselect;
1836
}
1837
1838
/**
1839
 * Helper function renders recording table.
1840
 *
1841
 * @param array $bbbsession
1842
 * @param array $recordings
1843
 * @param array $tools
1844
 *
1845
 * @return array
1846
 */
1847
function bigbluebuttonbn_output_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1848
    if (isset($recordings) && !empty($recordings)) {
1849
        // There are recordings for this meeting.
1850
        $table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools);
1851
    }
1852
    if (!isset($table) || !isset($table->data)) {
1853
        // Render a table with "No recordings".
1854
        return html_writer::div(get_string('view_message_norecordings', 'bigbluebuttonbn'), '',
1855
            array('id' => 'bigbluebuttonbn_recordings_table'));
1856
    }
1857
    // Render the table.
1858
    return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_recordings_table'));
1859
}
1860
1861
/**
1862
 * Helper function to convert an html string to plain text.
1863
 *
1864
 * @param string $html
1865
 * @param integer $len
1866
 *
1867
 * @return string
1868
 */
1869
function bigbluebuttonbn_html2text($html, $len = 0) {
1870
    $text = strip_tags($html);
1871
    $text = str_replace('&nbsp;', ' ', $text);
1872
    $textlen = strlen($text);
1873
    $text = substr($text, 0, $len);
1874
    if ($textlen > $len) {
1875
        $text .= '...';
1876
    }
1877
    return $text;
1878
}
1879
1880
/**
1881
 * Helper function to obtain the tags linked to a bigbluebuttonbn activity
1882
 *
1883
 * @param string $id
1884
 *
1885
 * @return string containing the tags separated by commas
1886
 */
1887
function bigbluebuttonbn_get_tags($id) {
1888
    if (class_exists('core_tag_tag')) {
1889
        return implode(',', core_tag_tag::get_item_tags_array('core', 'course_modules', $id));
1890
    }
1891
    return implode(',', tag_get_tags('bigbluebuttonbn', $id));
1892
}
1893
1894
/**
1895
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1896
 * in the getRecordings request
1897
 *
1898
 * @param string $courseid
1899
 * @param string $bigbluebuttonbnid
1900
 * @param bool   $subset
1901
 *
1902
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1903
 */
1904
function bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid = null, $subset = true) {
1905
    if (empty($courseid)) {
1906
        $courseid = 0;
1907
    }
1908
    if (empty($bigbluebuttonbnid)) {
1909
        return "course = '{$courseid}'";
1910
    }
1911
    if ($subset) {
1912
        return "id = '{$bigbluebuttonbnid}'";
1913
    }
1914
    return "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'";
1915
}
1916
1917
/**
1918
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1919
 * in the getRecordings request considering only those that belong to deleted activities.
1920
 *
1921
 * @param string $courseid
1922
 * @param string $bigbluebuttonbnid
1923
 * @param bool   $subset
1924
 *
1925
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1926
 */
1927 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...
1928
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_DELETE . "' AND meta like '%has_recordings%' AND meta like '%true%'";
1929
    if (empty($courseid)) {
1930
        $courseid = 0;
1931
    }
1932
    if (empty($bigbluebuttonbnid)) {
1933
        return $sql . " AND courseid = {$courseid}";
1934
    }
1935
    if ($subset) {
1936
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
1937
    }
1938
    return $sql . " AND courseid = {$courseid} AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
1939
}
1940
1941
/**
1942
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1943
 * in the getRecordings request considering only those that belong to imported recordings.
1944
 *
1945
 * @param string $courseid
1946
 * @param string $bigbluebuttonbnid
1947
 * @param bool   $subset
1948
 *
1949
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1950
 */
1951 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...
1952
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
1953
    if (empty($courseid)) {
1954
        $courseid = 0;
1955
    }
1956
    if (empty($bigbluebuttonbnid)) {
1957
        return $sql . " AND courseid = '{$courseid}'";
1958
    }
1959
    if ($subset) {
1960
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
1961
    }
1962
    return $sql . " AND courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
1963
}
1964
1965
/**
1966
 * Helper function to get recordings  and imported recordings together.
1967
 *
1968
 * @param string $courseid
1969
 * @param string $bigbluebuttonbnid
1970
 * @param bool   $subset
1971
 * @param bool   $includedeleted
1972
 *
1973
 * @return associative array containing the recordings indexed by recordID, each recording is also a
1974
 * non sequential associative array itself that corresponds to the actual recording in BBB
1975
 */
1976
function bigbluebuttonbn_get_allrecordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
1977
    $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $subset, $includedeleted);
1978
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset);
1979
    return ($recordings + $recordingsimported);
1980
}
1981
1982
/**
1983
 * Helper function to retrieve recordings from the BigBlueButton. The references are stored as events
1984
 * in bigbluebuttonbn_logs.
1985
 *
1986
 * @param string $courseid
1987
 * @param string $bigbluebuttonbnid
1988
 * @param bool   $subset
1989
 * @param bool   $includedeleted
1990
 *
1991
 * @return associative array containing the recordings indexed by recordID, each recording is also a
1992
 * non sequential associative array itself that corresponds to the actual recording in BBB
1993
 */
1994
function bigbluebuttonbn_get_recordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
1995
    global $DB;
1996
    $select = bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid, $subset);
1997
    $bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid');
1998
    /* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in
1999
     * the getRecordings request. */
2000
    if ($includedeleted) {
2001
        $selectdeleted = bigbluebuttonbn_get_recordings_deleted_sql_select($courseid, $bigbluebuttonbnid, $subset);
2002
        $bigbluebuttonbnsdel = $DB->get_records_select_menu('bigbluebuttonbn_logs', $selectdeleted, null,
2003
            'bigbluebuttonbnid', 'bigbluebuttonbnid, meetingid');
2004
        if (!empty($bigbluebuttonbnsdel)) {
2005
            // Merge bigbluebuttonbnis from deleted instances, only keys are relevant.
2006
            // Artimetic merge is used in order to keep the keys.
2007
            $bigbluebuttonbns += $bigbluebuttonbnsdel;
2008
        }
2009
    }
2010
    // Gather the meetingids from bigbluebuttonbn logs that include a create with record=true.
2011
    if (empty($bigbluebuttonbns)) {
2012
        return array();
2013
    }
2014
    // Prepare select for loading records based on existent bigbluebuttonbns.
2015
    $sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE ';
2016
    $sql .= '(bigbluebuttonbnid='.implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)).')';
2017
    // Include only Create events and exclude those with record not true.
2018
    $sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?';
2019
    // Execute select for loading records based on existent bigbluebuttonbns.
2020
    $records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%'));
2021
    // Get actual recordings.
2022
    return bigbluebuttonbn_get_recordings_array(array_keys($records));
2023
}
2024
2025
/**
2026
 * Helper function iterates an array with recordings and unset those already imported.
2027
 *
2028
 * @param array $recordings
2029
 * @param integer $courseid
2030
 * @param integer $bigbluebuttonbnid
2031
 *
2032
 * @return array
2033
 */
2034
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) {
2035
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true);
2036
    foreach ($recordings as $key => $recording) {
2037
        if (isset($recordingsimported[$recording['recordID']])) {
2038
            unset($recordings[$key]);
2039
        }
2040
    }
2041
    return $recordings;
2042
}
2043
2044
/**
2045
 * Helper function to count the imported recordings for a recordingid.
2046
 *
2047
 * @param string $recordid
2048
 *
2049
 * @return integer
2050
 */
2051
function bigbluebuttonbn_count_recording_imported_instances($recordid) {
2052
    global $DB;
2053
    $sql = 'SELECT COUNT(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2054
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%"));
2055
}
2056
2057
/**
2058
 * Helper function returns an array with all the instances of imported recordings for a recordingid.
2059
 *
2060
 * @param string $recordid
2061
 *
2062
 * @return array
2063
 */
2064
function bigbluebuttonbn_get_recording_imported_instances($recordid) {
2065
    global $DB;
2066
    $sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2067
    $recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%',
2068
        "%{$recordid}%"));
2069
    return $recordingsimported;
2070
}
2071
2072
/**
2073
 * Helper function returns an array with the profiles (with features per profile) for the different types
2074
 * of bigbluebuttonbn instances.
2075
 *
2076
 * @return array
2077
 */
2078
function bigbluebuttonbn_get_instance_type_profiles() {
2079
    $instanceprofiles = array(
2080
            array('id' => BIGBLUEBUTTONBN_TYPE_ALL, 'name' => get_string('instance_type_default', 'bigbluebuttonbn'),
2081
                'features' => array('all')),
2082
            array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY, 'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'),
2083
                'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit', 'recording',
2084
                    'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups',
2085
                    'modstandardelshdr', 'availabilityconditionsheader', 'tagshdr', 'competenciessection')),
2086
            array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY, 'name' => get_string('instance_type_recording_only',
2087
                'bigbluebuttonbn'), 'features' => array('showrecordings', 'importrecordings')),
2088
    );
2089
    return $instanceprofiles;
2090
}
2091
2092
/**
2093
 * Helper function returns an array with enabled features for an specific profile type.
2094
 *
2095
 * @param array $typeprofiles
2096
 * @param string $type
2097
 *
2098
 * @return array
2099
 */
2100
function bigbluebuttonbn_get_enabled_features($typeprofiles, $type = null) {
2101
    $enabledfeatures = array();
2102
    $features = $typeprofiles[0]['features'];
2103
    if (!is_null($type)) {
2104
        $features = $typeprofiles[$type]['features'];
2105
    }
2106
    $enabledfeatures['showroom'] = (in_array('all', $features) || in_array('showroom', $features));
2107
    // Evaluates if recordings are enabled for the Moodle site.
2108
    $enabledfeatures['showrecordings'] = false;
2109
    if (\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
2110
        $enabledfeatures['showrecordings'] = (in_array('all', $features) || in_array('showrecordings', $features));
2111
    }
2112
    $enabledfeatures['importrecordings'] = false;
2113
    if (\mod_bigbluebuttonbn\locallib\config::importrecordings_enabled()) {
2114
        $enabledfeatures['importrecordings'] = (in_array('all', $features) || in_array('importrecordings', $features));
2115
    }
2116
    return $enabledfeatures;
2117
}
2118
2119
/**
2120
 * Helper function returns an array with the profiles (with features per profile) for the different types
2121
 * of bigbluebuttonbn instances.
2122
 *
2123
 * @param array $profiles
2124
 *
2125
 * @return array
2126
 */
2127
function bigbluebuttonbn_get_instance_profiles_array($profiles = null) {
2128
    if (is_null($profiles) || empty($profiles)) {
2129
        $profiles = bigbluebuttonbn_get_instance_type_profiles();
2130
    }
2131
    $profilesarray = array();
2132
    foreach ($profiles as $profile) {
2133
        $profilesarray += array("{$profile['id']}" => $profile['name']);
2134
    }
2135
    return $profilesarray;
2136
}
2137
2138
/**
2139
 * Helper function returns time in a formatted string.
2140
 *
2141
 * @param integer $time
2142
 *
2143
 * @return string
2144
 */
2145
function bigbluebuttonbn_format_activity_time($time) {
2146
    $activitytime = '';
2147
    if ($time) {
2148
        $activitytime = calendar_day_representation($time).' '.
2149
          get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn').' '.
2150
          calendar_time_representation($time);
2151
    }
2152
    return $activitytime;
2153
}
2154
2155
/**
2156
 * Helper function returns array with all the strings to be used in javascript.
2157
 *
2158
 * @return array
2159
 */
2160
function bigbluebuttonbn_get_strings_for_js() {
2161
    $locale = bigbluebuttonbn_get_locale();
2162
    $stringman = get_string_manager();
2163
    $strings = $stringman->load_component_strings('bigbluebuttonbn', $locale);
2164
    return $strings;
2165
}
2166
2167
/**
2168
 * Helper function returns the locale set by moodle.
2169
 *
2170
 * @return string
2171
 */
2172
function bigbluebuttonbn_get_locale() {
2173
    $lang = get_string('locale', 'core_langconfig');
2174
    return substr($lang, 0, strpos($lang, '.'));
2175
}
2176
2177
/**
2178
 * Helper function returns the locale code based on the locale set by moodle.
2179
 *
2180
 * @return string
2181
 */
2182
function bigbluebuttonbn_get_localcode() {
2183
    $locale = bigbluebuttonbn_get_locale();
2184
    return substr($locale, 0, strpos($locale, '_'));
2185
}
2186
2187
/**
2188
 * Helper function returns array with the instance settings used in views.
2189
 *
2190
 * @param string $id
2191
 * @param object $bigbluebuttonbnid
2192
 *
2193
 * @return array
2194
 */
2195
function bigbluebuttonbn_view_validator($id, $bigbluebuttonbnid) {
2196
    if ($id) {
2197
        return bigbluebuttonbn_view_instance_id($id);
2198
    }
2199
    if ($bigbluebuttonbnid) {
2200
        return bigbluebuttonbn_view_instance_bigbluebuttonbn($bigbluebuttonbnid);
2201
    }
2202
    return;
2203
}
2204
2205
/**
2206
 * Helper function returns array with the instance settings used in views based on id.
2207
 *
2208
 * @param string $id
2209
 *
2210
 * @return array
2211
 */
2212 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...
2213
    global $DB;
2214
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2215
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2216
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2217
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2218
}
2219
2220
/**
2221
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2222
 *
2223
 * @param object $bigbluebuttonbnid
2224
 *
2225
 * @return array
2226
 */
2227 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...
2228
    global $DB;
2229
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2230
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2231
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2232
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2233
}
2234
2235
/**
2236
 * Helper function renders general warning message for settings (if any).
2237
 *
2238
 * @param object $renderer
2239
 *
2240
 * @return void
2241
 */
2242
function bigbluebuttonbn_settings_general_warning(&$renderer) {
0 ignored issues
show
Unused Code introduced by
The parameter $renderer 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...
2243
    return;
2244
}
2245
2246
/**
2247
 * Helper function renders general settings if the feature is enabled.
2248
 *
2249
 * @param object $renderer
2250
 *
2251
 * @return void
2252
 */
2253
function bigbluebuttonbn_settings_general(&$renderer) {
2254
    // Configuration for BigBlueButton.
2255
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_general_shown()) {
2256
        $renderer->render_group_header('general');
2257
        $renderer->render_group_element('server_url',
2258
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL));
2259
        $renderer->render_group_element('shared_secret',
2260
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET));
2261
    }
2262
}
2263
2264
/**
2265
 * Helper function renders record settings if the feature is enabled.
2266
 *
2267
 * @param object $renderer
2268
 *
2269
 * @return void
2270
 */
2271
function bigbluebuttonbn_settings_record(&$renderer) {
2272
    // Configuration for 'recording' feature.
2273 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_record_meeting_shown()) {
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...
2274
        $renderer->render_group_header('recording');
2275
        $renderer->render_group_element('recording_default',
2276
            $renderer->render_group_element_checkbox('recording_default', 1));
2277
        $renderer->render_group_element('recording_editable',
2278
            $renderer->render_group_element_checkbox('recording_editable', 1));
2279
        $renderer->render_group_element('recording_icons_enabled',
2280
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1));
2281
    }
2282
}
2283
2284
/**
2285
 * Helper function renders import recording settings if the feature is enabled.
2286
 *
2287
 * @param object $renderer
2288
 *
2289
 * @return void
2290
 */
2291 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...
2292
    // Configuration for 'import recordings' feature.
2293
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_import_recordings_shown()) {
2294
        $renderer->render_group_header('importrecordings');
2295
        $renderer->render_group_element('importrecordings_enabled',
2296
            $renderer->render_group_element_checkbox('importrecordings_enabled', 0));
2297
        $renderer->render_group_element('importrecordings_from_deleted_enabled',
2298
            $renderer->render_group_element_checkbox('importrecordings_from_deleted_enabled', 0));
2299
    }
2300
}
2301
2302
/**
2303
 * Helper function renders show recording settings if the feature is enabled.
2304
 *
2305
 * @param object $renderer
2306
 *
2307
 * @return void
2308
 */
2309
function bigbluebuttonbn_settings_showrecordings(&$renderer) {
2310
    // Configuration for 'show recordings' feature.
2311
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_show_recordings_shown()) {
2312
        $renderer->render_group_header('recordings');
2313
        $renderer->render_group_element('recordings_html_default',
2314
            $renderer->render_group_element_checkbox('recordings_html_default', 1));
2315
        $renderer->render_group_element('recordings_html_editable',
2316
            $renderer->render_group_element_checkbox('recordings_html_editable', 0));
2317
        $renderer->render_group_element('recordings_deleted_default',
2318
            $renderer->render_group_element_checkbox('recordings_deleted_default', 1));
2319
        $renderer->render_group_element('recordings_deleted_editable',
2320
            $renderer->render_group_element_checkbox('recordings_deleted_editable', 0));
2321
        $renderer->render_group_element('recordings_imported_default',
2322
            $renderer->render_group_element_checkbox('recordings_imported_default', 0));
2323
        $renderer->render_group_element('recordings_imported_editable',
2324
            $renderer->render_group_element_checkbox('recordings_imported_editable', 1));
2325
        $renderer->render_group_element('recordings_preview_default',
2326
            $renderer->render_group_element_checkbox('recordings_preview_default', 1));
2327
        $renderer->render_group_element('recordings_preview_editable',
2328
            $renderer->render_group_element_checkbox('recordings_preview_editable', 0));
2329
    }
2330
}
2331
2332
/**
2333
 * Helper function renders wait for moderator settings if the feature is enabled.
2334
 *
2335
 * @param object $renderer
2336
 *
2337
 * @return void
2338
 */
2339
function bigbluebuttonbn_settings_waitmoderator(&$renderer) {
2340
    // Configuration for wait for moderator feature.
2341
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_wait_moderator_shown()) {
2342
        $renderer->render_group_header('waitformoderator');
2343
        $renderer->render_group_element('waitformoderator_default',
2344
            $renderer->render_group_element_checkbox('waitformoderator_default', 0));
2345
        $renderer->render_group_element('waitformoderator_editable',
2346
            $renderer->render_group_element_checkbox('waitformoderator_editable', 1));
2347
        $renderer->render_group_element('waitformoderator_ping_interval',
2348
            $renderer->render_group_element_text('waitformoderator_ping_interval', 10, PARAM_INT));
2349
        $renderer->render_group_element('waitformoderator_cache_ttl',
2350
            $renderer->render_group_element_text('waitformoderator_cache_ttl', 60, PARAM_INT));
2351
    }
2352
}
2353
2354
/**
2355
 * Helper function renders static voice bridge settings if the feature is enabled.
2356
 *
2357
 * @param object $renderer
2358
 *
2359
 * @return void
2360
 */
2361
function bigbluebuttonbn_settings_voicebridge(&$renderer) {
2362
    // Configuration for "static voice bridge" feature.
2363
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_static_voice_bridge_shown()) {
2364
        $renderer->render_group_header('voicebridge');
2365
        $renderer->render_group_element('voicebridge_editable',
2366
            $renderer->render_group_element_checkbox('voicebridge_editable', 0));
2367
    }
2368
}
2369
2370
/**
2371
 * Helper function renders preuploaded presentation settings if the feature is enabled.
2372
 *
2373
 * @param object $renderer
2374
 *
2375
 * @return void
2376
 */
2377
function bigbluebuttonbn_settings_preupload(&$renderer) {
2378
    // Configuration for "preupload presentation" feature.
2379
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_preupload_presentation_shown()) {
2380
        // This feature only works if curl is installed.
2381
        $preuploaddescripion = get_string('config_preuploadpresentation_description', 'bigbluebuttonbn');
2382
        if (!extension_loaded('curl')) {
2383
            $preuploaddescripion .= '<div class="form-defaultinfo">';
2384
            $preuploaddescripion .= get_string('config_warning_curl_not_installed', 'bigbluebuttonbn');
2385
            $preuploaddescripion .= '</div><br>';
2386
        }
2387
        $renderer->render_group_header('preuploadpresentation', null, $preuploaddescripion);
2388
        if (extension_loaded('curl')) {
2389
            $renderer->render_group_element('preuploadpresentation_enabled',
2390
                $renderer->render_group_element_checkbox('preuploadpresentation_enabled', 0));
2391
        }
2392
    }
2393
}
2394
2395
/**
2396
 * Helper function renders userlimit settings if the feature is enabled.
2397
 *
2398
 * @param object $renderer
2399
 *
2400
 * @return void
2401
 */
2402
function bigbluebuttonbn_settings_userlimit(&$renderer) {
2403
    // Configuration for "user limit" feature.
2404
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_user_limit_shown()) {
2405
        $renderer->render_group_header('userlimit');
2406
        $renderer->render_group_element('userlimit_default',
2407
            $renderer->render_group_element_text('userlimit_default', 0, PARAM_INT));
2408
        $renderer->render_group_element('userlimit_editable',
2409
            $renderer->render_group_element_checkbox('userlimit_editable', 0));
2410
    }
2411
}
2412
2413
/**
2414
 * Helper function renders duration settings if the feature is enabled.
2415
 *
2416
 * @param object $renderer
2417
 *
2418
 * @return void
2419
 */
2420
function bigbluebuttonbn_settings_duration(&$renderer) {
2421
    // Configuration for "scheduled duration" feature.
2422 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_scheduled_duration_shown()) {
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...
2423
        $renderer->render_group_header('scheduled');
2424
        $renderer->render_group_element('scheduled_duration_enabled',
2425
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1));
2426
        $renderer->render_group_element('scheduled_duration_compensation',
2427
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT));
2428
        $renderer->render_group_element('scheduled_pre_opening',
2429
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT));
2430
    }
2431
}
2432
2433
/**
2434
 * Helper function renders participant settings if the feature is enabled.
2435
 *
2436
 * @param object $renderer
2437
 *
2438
 * @return void
2439
 */
2440
function bigbluebuttonbn_settings_participants(&$renderer) {
2441
    // Configuration for defining the default role/user that will be moderator on new activities.
2442
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_moderator_default_shown()) {
2443
        $renderer->render_group_header('participant');
2444
        // UI for 'participants' feature.
2445
        $roles = bigbluebuttonbn_get_roles();
2446
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2447
        $renderer->render_group_element('participant_moderator_default',
2448
            $renderer->render_group_element_configmultiselect('participant_moderator_default',
2449
                array_keys($owner), array_merge($owner, $roles))
2450
          );
2451
    }
2452
}
2453
2454
/**
2455
 * Helper function renders notification settings if the feature is enabled.
2456
 *
2457
 * @param object $renderer
2458
 *
2459
 * @return void
2460
 */
2461
function bigbluebuttonbn_settings_notifications(&$renderer) {
2462
    // Configuration for "send notifications" feature.
2463
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_send_notifications_shown()) {
2464
        $renderer->render_group_header('sendnotifications');
2465
        $renderer->render_group_element('sendnotifications_enabled',
2466
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1));
2467
    }
2468
}
2469
2470
/**
2471
 * Helper function renders extended settings if any of the features there is enabled.
2472
 *
2473
 * @param object $renderer
2474
 *
2475
 * @return void
2476
 */
2477 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...
2478
    // Configuration for extended BN capabilities.
2479
    if (!bigbluebuttonbn_is_bn_server()) {
2480
        return;
2481
    }
2482
    // Configuration for 'notify users when recording ready' feature.
2483
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_settings_extended_shown()) {
2484
        $renderer->render_group_header('extended_capabilities');
2485
        // UI for 'notify users when recording ready' feature.
2486
        $renderer->render_group_element('recordingready_enabled',
2487
            $renderer->render_group_element_checkbox('recordingready_enabled', 0));
2488
        // UI for 'register meeting events' feature.
2489
        $renderer->render_group_element('meetingevents_enabled',
2490
            $renderer->render_group_element_checkbox('meetingevents_enabled', 0));
2491
    }
2492
}
2493
2494
/**
2495
 * Helper function returns an encoded meetingid.
2496
 *
2497
 * @param string $seed
2498
 *
2499
 * @return string
2500
 */
2501
function bigbluebuttonbn_encode_meetingid($seed) {
2502
    global $CFG;
2503
    return sha1($CFG->wwwroot . $seed . \mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
2504
}
2505
2506
/**
2507
 * Helper function renders the link used for recording type in row for the data used by the recording table.
2508
 *
2509
 * @param array $recording
2510
 * @param array $bbbsession
2511
 * @param array $playback
2512
 *
2513
 * @return boolean
2514
 */
2515
function bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback) {
2516
    // All types that are not statistics are included.
2517
    if ($playback['type'] != 'statistics') {
2518
        return true;
2519
    }
2520
    // Exclude imported recordings.
2521
    if (isset($recording['imported'])) {
2522
        return false;
2523
    }
2524
    // Exclude non moderators.
2525
    if (!$bbbsession['administrator'] && !$bbbsession['moderator']) {
2526
        return false;
2527
    }
2528
    return true;
2529
}
2530
2531
/**
2532
 * Renders the general warning message.
2533
 *
2534
 * @param string $message
2535
 * @param string $type
2536
 * @param string $href
2537
 * @param string $text
2538
 * @param string $class
2539
 *
2540
 * @return string
2541
 */
2542
function bigbluebuttonbn_render_warning($message, $type='info', $href='', $text='', $class='') {
2543
    global $OUTPUT;
2544
    $output = "\n";
2545
    // Evaluates if config_warning is enabled.
2546
    if (empty($message)) {
2547
        return $output;
2548
    }
2549
    $output .= $OUTPUT->box_start('box boxalignleft adminerror alert alert-' . $type . ' alert-block fade in',
2550
      'bigbluebuttonbn_view_general_warning') . "\n";
2551
    $output .= '    ' . $message . "\n";
2552
    $output .= '  <div class="singlebutton pull-right">' . "\n";
2553
    if (!empty($href)) {
2554
        $output .= bigbluebuttonbn_render_warning_button($href, $text, $class);
2555
    }
2556
    $output .= '  </div>' . "\n";
2557
    $output .= $OUTPUT->box_end() . "\n";
2558
    return $output;
2559
}
2560
2561
/**
2562
 * Renders the general warning button.
2563
 *
2564
 * @param string $href
2565
 * @param string $text
2566
 * @param string $class
2567
 * @param string $title
2568
 *
2569
 * @return string
2570
 */
2571
function bigbluebuttonbn_render_warning_button($href, $text = '', $class = '', $title = '') {
2572
    if ($text == '') {
2573
        $text = get_string('ok', 'moodle');
2574
    }
2575
    if ($title == '') {
2576
        $title = $text;
2577
    }
2578
    if ($class == '') {
2579
        $class = 'btn btn-secondary';
2580
    }
2581
    $output  = '  <form method="post" action="' . $href . '" class="form-inline">'."\n";
2582
    $output .= '      <button type="submit" class="' . $class . '"'."\n";
2583
    $output .= '          title="' . $title . '"'."\n";
2584
    $output .= '          >' . $text . '</button>'."\n";
2585
    $output .= '  </form>'."\n";
2586
    return $output;
2587
}
2588