Completed
Pull Request — master (#44)
by Jesus
02:05
created

vent_log()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 4
rs 10
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-2017 Blindside Networks Inc
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v2 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
/** @var BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED string defines the bigbluebuttonbn activity_viewed event */
46
const BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED = 'activity_viewed';
47
/** @var BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED string defines the bigbluebuttonbn activity_management_viewed event */
48
const BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED = 'activity_management_viewed';
49
/** @var BIGBLUEBUTTON_EVENT_LIVE_SESSION string defines the bigbluebuttonbn live_session event */
50
const BIGBLUEBUTTON_EVENT_LIVE_SESSION = 'live_session';
51
/** @var BIGBLUEBUTTON_EVENT_MEETING_CREATED string defines the bigbluebuttonbn meeting_created event */
52
const BIGBLUEBUTTON_EVENT_MEETING_CREATED = 'meeting_created';
53
/** @var BIGBLUEBUTTON_EVENT_MEETING_ENDED string defines the bigbluebuttonbn meeting_ended event */
54
const BIGBLUEBUTTON_EVENT_MEETING_ENDED = 'meeting_ended';
55
/** @var BIGBLUEBUTTON_EVENT_MEETING_JOINED string defines the bigbluebuttonbn meeting_joined event */
56
const BIGBLUEBUTTON_EVENT_MEETING_JOINED = 'meeting_joined';
57
/** @var BIGBLUEBUTTON_EVENT_MEETING_LEFT string defines the bigbluebuttonbn meeting_left event */
58
const BIGBLUEBUTTON_EVENT_MEETING_LEFT = 'meeting_left';
59
/** @var BIGBLUEBUTTON_EVENT_RECORDING_DELETED string defines the bigbluebuttonbn recording_deleted event */
60
const BIGBLUEBUTTON_EVENT_RECORDING_DELETED = 'recording_deleted';
61
/** @var BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED string defines the bigbluebuttonbn recording_imported event */
62
const BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED = 'recording_imported';
63
/** @var BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED string defines the bigbluebuttonbn recording_protected event */
64
const BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED = 'recording_protected';
65
/** @var BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED string defines the bigbluebuttonbn recording_published event */
66
const BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED = 'recording_published';
67
/** @var BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED string defines the bigbluebuttonbn recording_unprotected event */
68
const BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED = 'recording_unprotected';
69
/** @var BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED string defines the bigbluebuttonbn recording_unpublished event */
70
const BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED = 'recording_unpublished';
71
/** @var BIGBLUEBUTTON_EVENT_RECORDING_EDITED string defines the bigbluebuttonbn recording_edited event */
72
const BIGBLUEBUTTON_EVENT_RECORDING_EDITED = 'recording_edited';
73
/** @var BIGBLUEBUTTON_EVENT_RECORDING_VIEWED string defines the bigbluebuttonbn recording_viewed event */
74
const BIGBLUEBUTTON_EVENT_RECORDING_VIEWED = 'recording_viewed';
75
76
/**
77
 * Register a bigbluebuttonbn event
78
 *
79
 * @param array  $bbbsession
80
 * @param string $event
81
 * @param array  $overrides
82
 * @param string $meta
83
 *
84
 * @return void
85
 */
86
function bigbluebuttonbn_logs(array $bbbsession, $event, array $overrides = [], $meta = null) {
87
    global $DB;
88
    $log = new stdClass();
89
    // Default values.
90
    $log->courseid = $bbbsession['course']->id;
91
    $log->bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
92
    $log->userid = $bbbsession['userID'];
93
    $log->meetingid = $bbbsession['meetingid'];
94
    $log->timecreated = time();
95
    // Overrides.
96
    foreach ($overrides as $key => $value) {
97
        $log->$key = $value;
98
    }
99
    $log->log = $event;
100
    if (isset($meta)) {
101
        $log->meta = $meta;
102
    } else if ($event == BIGBLUEBUTTONBN_LOG_EVENT_CREATE) {
103
        $log->meta = '{"record":'.($bbbsession['record'] ? 'true' : 'false').'}';
104
    }
105
    $DB->insert_record('bigbluebuttonbn_logs', $log);
106
}
107
108
/**
109
 * Builds and retunrs a url for joining a bigbluebutton meeting.
110
 *
111
 * @param string $meetingid
112
 * @param string $username
113
 * @param string $pw
114
 * @param string $logouturl
115
 * @param string $configtoken
116
 * @param string $userid
117
 *
118
 * @return string
119
 */
120
function bigbluebuttonbn_get_join_url($meetingid, $username, $pw, $logouturl, $configtoken = null, $userid = null) {
121
    $data = ['meetingID' => $meetingid,
122
              'fullName' => $username,
123
              'password' => $pw,
124
              'logoutURL' => $logouturl,
125
            ];
126
    if (!is_null($configtoken)) {
127
        $data['configToken'] = $configtoken;
128
    }
129
    if (!is_null($userid)) {
130
        $data['userID'] = $userid;
131
    }
132
    return \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('join', $data);
133
}
134
135
/**
136
 * Creates a bigbluebutton meeting and returns the response in an array.
137
 *
138
 * @param array  $data
139
 * @param array  $metadata
140
 * @param string $pname
141
 * @param string $purl
142
 *
143
 * @return array
144
 */
145
function bigbluebuttonbn_get_create_meeting_array($data, $metadata = array(), $pname = null, $purl = null) {
146
    $createmeetingurl = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('create', $data, $metadata);
147
    $method = 'GET';
148
    $data = null;
149
    if (!is_null($pname) && !is_null($purl)) {
150
        $method = 'POST';
151
        $data = "<?xml version='1.0' encoding='UTF-8'?><modules><module name='presentation'><document url='".
152
            $purl."' /></module></modules>";
153
    }
154
    $xml = bigbluebuttonbn_wrap_xml_load_file($createmeetingurl, $method, $data);
155
    if ($xml) {
156
        $response = array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
157
        if ($xml->meetingID) {
158
            $response += array('meetingID' => $xml->meetingID, 'attendeePW' => $xml->attendeePW,
159
                'moderatorPW' => $xml->moderatorPW, 'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded);
160
        }
161
        return $response;
162
    }
163
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
164
}
165
166
/**
167
 * Fetch meeting info and wrap response in array.
168
 *
169
 * @param string $meetingid
170
 *
171
 * @return array
172
 */
173
function bigbluebuttonbn_get_meeting_info_array($meetingid) {
174
    $xml = bigbluebuttonbn_wrap_xml_load_file(
175
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
176
      );
177
    if ($xml && $xml->returncode == 'SUCCESS' && empty($xml->messageKey)) {
178
        // Meeting info was returned.
179
        return array('returncode' => $xml->returncode,
180
                     'meetingID' => $xml->meetingID,
181
                     'moderatorPW' => $xml->moderatorPW,
182
                     'attendeePW' => $xml->attendeePW,
183
                     'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded,
184
                     'running' => $xml->running,
185
                     'recording' => $xml->recording,
186
                     'startTime' => $xml->startTime,
187
                     'endTime' => $xml->endTime,
188
                     'participantCount' => $xml->participantCount,
189
                     'moderatorCount' => $xml->moderatorCount,
190
                     'attendees' => $xml->attendees,
191
                     'metadata' => $xml->metadata,
192
                   );
193
    }
194
    if ($xml) {
195
        // Either failure or success without meeting info.
196
        return (array)$xml;
197
    }
198
    // If the server is unreachable, then prompts the user of the necessary action.
199
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
200
}
201
202
/**
203
 * Helper function to retrieve recordings from a BigBlueButton server.
204
 *
205
 * @param string|array $meetingids   list of meetingIDs "mid1,mid2,mid3" or array("mid1","mid2","mid3")
206
 * @param string|array $recordingids list of $recordingids "rid1,rid2,rid3" or array("rid1","rid2","rid3") for filtering
207
 *
208
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
209
 */
210
function bigbluebuttonbn_get_recordings_array($meetingids, $recordingids = []) {
211
    $meetingidsarray = $meetingids;
212
    if (!is_array($meetingids)) {
213
        $meetingidsarray = explode(',', $meetingids);
214
    }
215
    // If $meetingidsarray is empty there is no need to go further.
216
    if (empty($meetingidsarray)) {
217
        return array();
218
    }
219
    $recordings = bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray);
0 ignored issues
show
Bug introduced by
It seems like $meetingidsarray defined by $meetingids on line 211 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...
220
    // Sort recordings.
221
    uasort($recordings, 'bigbluebuttonbn_recording_build_sorter');
222
    // Filter recordings based on recordingIDs.
223
    $recordingidsarray = $recordingids;
224
    if (!is_array($recordingids)) {
225
        $recordingidsarray = explode(',', $recordingids);
226
    }
227
    if (empty($recordingidsarray)) {
228
        // No recording ids, no need to filter.
229
        return $recordings;
230
    }
231
    return bigbluebuttonbn_get_recordings_array_filter($recordingidsarray, $recordings);
0 ignored issues
show
Bug introduced by
It seems like $recordingidsarray defined by $recordingids on line 223 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...
232
}
233
234
/**
235
 * Helper function to fetch recordings from a BigBlueButton server.
236
 *
237
 * @param array $meetingidsarray   array with meeting ids in the form array("mid1","mid2","mid3")
238
 *
239
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
240
 */
241
function bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray) {
242
    $recordings = array();
243
    // Execute a paginated getRecordings request.
244
    $pages = floor(count($meetingidsarray) / 25) + 1;
245
    for ($page = 1; $page <= $pages; ++$page) {
246
        $mids = array_slice($meetingidsarray, ($page - 1) * 25, 25);
247
        $recordings += bigbluebuttonbn_get_recordings_array_fetch_page($mids);
248
    }
249
    return $recordings;
250
}
251
252
/**
253
 * Helper function to fetch one page of upto 25 recordings from a BigBlueButton server.
254
 *
255
 * @param array  $mids
256
 *
257
 * @return array
258
 */
259
function bigbluebuttonbn_get_recordings_array_fetch_page($mids) {
260
    $recordings = array();
261
    // Do getRecordings is executed using a method GET (supported by all versions of BBB).
262
    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings', ['meetingID' => implode(',', $mids)]);
263
    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
264
    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
265
        // If there were meetings already created.
266
        foreach ($xml->recordings->recording as $recordingxml) {
267
            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
268
            $recordings[$recording['recordID']] = $recording;
269
        }
270
    }
271
    return $recordings;
272
}
273
274
/**
275
 * Helper function to remove a set of recordings from an array.
276
 *
277
 * @param array  $rids
278
 * @param array  $recordings
279
 *
280
 * @return array
281
 */
282
function bigbluebuttonbn_get_recordings_array_filter($rids, &$recordings) {
283
    foreach ($recordings as $key => $recording) {
284
        if (!in_array($recording['recordID'], $rids)) {
285
            unset($recordings[$key]);
286
        }
287
    }
288
    return $recordings;
289
}
290
291
/**
292
 * Helper function to retrieve imported recordings from the Moodle database.
293
 * The references are stored as events in bigbluebuttonbn_logs.
294
 *
295
 * @param string $courseid
296
 * @param string $bigbluebuttonbnid
297
 * @param bool   $subset
298
 *
299
 * @return associative array with imported recordings indexed by recordID, each recording is a non sequential associative
300
 * array that corresponds to the actual recording in BBB
301
 */
302
function bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid = null, $subset = true) {
303
    global $DB;
304
    $select = "courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}' AND log = '" .
305
        BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
306
    if ($bigbluebuttonbnid === null) {
307
        $select = "courseid = '{$courseid}' AND log = '" . BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
308
    } else if ($subset) {
309
        $select = "bigbluebuttonbnid = '{$bigbluebuttonbnid}' AND log = '" . BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
310
    }
311
    $recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select);
312
    $recordsimportedarray = array();
313
    foreach ($recordsimported as $recordimported) {
314
        $meta = json_decode($recordimported->meta, true);
315
        $recording = $meta['recording'];
316
        // Override imported flag with actual ID.
317
        $recording['imported'] = $recordimported->id;
318
        if (isset($recordimported->protected)) {
319
            $recording['protected'] = (string) $recordimported->protected;
320
        }
321
        $recordsimportedarray[$recording['recordID']] = $recording;
322
    }
323
    return $recordsimportedarray;
324
}
325
326
/**
327
 * Helper function to retrive the default config.xml file.
328
 *
329
 * @return string
330
 */
331
function bigbluebuttonbn_get_default_config_xml() {
332
    $xml = bigbluebuttonbn_wrap_xml_load_file(
333
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getDefaultConfigXML')
334
      );
335
    return $xml;
336
}
337
338
/**
339
 * Helper function to convert an xml recording object to an array in the format used by the plugin.
340
 *
341
 * @param object $recording
342
 *
343
 * @return array
344
 */
345
function bigbluebuttonbn_get_recording_array_value($recording) {
346
    // Add formats.
347
    $playbackarray = array();
348
    foreach ($recording->playback->format as $format) {
349
        $playbackarray[(string) $format->type] = array('type' => (string) $format->type,
350
            'url' => trim((string) $format->url), 'length' => (string) $format->length);
351
        // Add preview per format when existing.
352
        if ($format->preview) {
353
            $imagesarray = array();
354
            foreach ($format->preview->images->image as $image) {
355
                $imagearray = array('url' => trim((string) $image));
356
                foreach ($image->attributes() as $attkey => $attvalue) {
357
                    $imagearray[$attkey] = (string) $attvalue;
358
                }
359
                array_push($imagesarray, $imagearray);
360
            }
361
            $playbackarray[(string) $format->type]['preview'] = $imagesarray;
362
        }
363
    }
364
    // Add the metadata to the recordings array.
365
    $metadataarray = bigbluebuttonbn_get_recording_array_meta(get_object_vars($recording->metadata));
0 ignored issues
show
Documentation introduced by
get_object_vars($recording->metadata) is of type array, but the function expects a object.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
366
    $recordingarray = array('recordID' => (string) $recording->recordID,
367
        'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
368
        'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
369
        'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray);
370
    if (isset($recording->protected)) {
371
        $recordingarray['protected'] = (string) $recording->protected;
372
    }
373
    return $recordingarray + $metadataarray;
374
}
375
376
/**
377
 * Helper function to convert an xml recording metadata object to an array in the format used by the plugin.
378
 *
379
 * @param object $metadata
380
 *
381
 * @return array
382
 */
383
function bigbluebuttonbn_get_recording_array_meta($metadata) {
384
    $metadataarray = array();
385
    foreach ($metadata as $key => $value) {
386
        if (is_object($value)) {
387
            $value = '';
388
        }
389
        $metadataarray['meta_'.$key] = $value;
390
    }
391
    return $metadataarray;
392
}
393
394
/**
395
 * Helper function to sort an array of recordings. It compares the startTime in two recording objecs.
396
 *
397
 * @param object $a
398
 * @param object $b
399
 *
400
 * @return array
401
 */
402
function bigbluebuttonbn_recording_build_sorter($a, $b) {
403
    if ($a['startTime'] < $b['startTime']) {
404
        return -1;
405
    }
406
    if ($a['startTime'] == $b['startTime']) {
407
        return 0;
408
    }
409
    return 1;
410
}
411
412
/**
413
 * Perform deleteRecordings on BBB.
414
 *
415
 * @param string $recordids
416
 *
417
 * @return boolean
418
 */
419 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...
420
    $ids = explode(',', $recordids);
421
    foreach ($ids as $id) {
422
        $xml = bigbluebuttonbn_wrap_xml_load_file(
423
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('deleteRecordings', ['recordID' => $id])
424
          );
425
        if ($xml && $xml->returncode != 'SUCCESS') {
426
            return false;
427
        }
428
    }
429
    return true;
430
}
431
432
/**
433
 * Perform publishRecordings on BBB.
434
 *
435
 * @param string $recordids
436
 * @param string $publish
437
 */
438 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...
439
    $ids = explode(',', $recordids);
440
    foreach ($ids as $id) {
441
        $xml = bigbluebuttonbn_wrap_xml_load_file(
442
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish])
443
          );
444
        if ($xml && $xml->returncode != 'SUCCESS') {
445
            return false;
446
        }
447
    }
448
    return true;
449
}
450
451
/**
452
 * Perform updateRecordings on BBB.
453
 *
454
 * @param string $recordids
455
 * @param array $params ['key'=>param_key, 'value']
456
 */
457 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...
458
    $ids = explode(',', $recordids);
459
    foreach ($ids as $id) {
460
        $xml = bigbluebuttonbn_wrap_xml_load_file(
461
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('updateRecordings', ['recordID' => $id] + (array) $params)
462
          );
463
        if ($xml && $xml->returncode != 'SUCCESS') {
464
            return false;
465
        }
466
    }
467
    return true;
468
}
469
470
/**
471
 * Perform end on BBB.
472
 *
473
 * @param string $meetingid
474
 * @param string $modpw
475
 */
476
function bigbluebuttonbn_end_meeting($meetingid, $modpw) {
477
    $xml = bigbluebuttonbn_wrap_xml_load_file(
478
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('end', ['meetingID' => $meetingid, 'password' => $modpw])
479
      );
480
    if ($xml) {
481
        // If the xml packet returned failure it displays the message to the user.
482
        return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
483
    }
484
    // If the server is unreachable, then prompts the user of the necessary action.
485
    return null;
486
}
487
488
/**
489
 * Perform isMeetingRunning on BBB.
490
 *
491
 * @param string $meetingid
492
 */
493
function bigbluebuttonbn_is_meeting_running($meetingid) {
494
    /* As a workaround to isMeetingRunning that always return SUCCESS but only returns true
495
     * when at least one user is in the session, we use getMeetingInfo instead.
496
     */
497
    $xml = bigbluebuttonbn_wrap_xml_load_file(
498
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
499
      );
500
    return ($xml && $xml->returncode == 'SUCCESS');
501
}
502
503
/**
504
 * Perform api request on BBB.
505
 *
506
 * @return string
507
 */
508
function bigbluebuttonbn_get_server_version() {
509
    $xml = bigbluebuttonbn_wrap_xml_load_file(
510
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url()
511
      );
512
    if ($xml && $xml->returncode == 'SUCCESS') {
513
        return $xml->version;
514
    }
515
    return null;
516
}
517
518
/**
519
 * Perform api request on BBB and wraps the response in an XML object
520
 *
521
 * @param string $url
522
 * @param string $method
523
 * @param string $data
524
 * @param string $contenttype
525
 *
526
 * @return object
527
 */
528
function bigbluebuttonbn_wrap_xml_load_file($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
529
    if (extension_loaded('curl')) {
530
        $response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype);
531
        if (!$response) {
532
            debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER);
533
            return null;
534
        }
535
        $previous = libxml_use_internal_errors(true);
536
        try {
537
            $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
538
            return $xml;
539
        } catch (Exception $e) {
540
            libxml_use_internal_errors($previous);
541
            $error = 'Caught exception: '.$e->getMessage();
542
            debugging($error, DEBUG_DEVELOPER);
543
            return null;
544
        }
545
    }
546
    // Alternative request non CURL based.
547
    $previous = libxml_use_internal_errors(true);
548
    try {
549
        $response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
550
        return $response;
551
    } catch (Exception $e) {
552
        $error = 'Caught exception: '.$e->getMessage();
553
        debugging($error, DEBUG_DEVELOPER);
554
        libxml_use_internal_errors($previous);
555
        return null;
556
    }
557
}
558
559
/**
560
 * Perform api request on BBB using CURL and wraps the response in an XML object
561
 *
562
 * @param string $url
563
 * @param string $method
564
 * @param string $data
565
 * @param string $contenttype
566
 *
567
 * @return object
568
 */
569
function bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
570
    $c = new curl();
571
    $c->setopt(array('SSL_VERIFYPEER' => true));
572
    if ($method == 'POST') {
573
        if (is_null($data) || is_array($data)) {
574
            return $c->post($url);
575
        }
576
577
        $options = array();
578
        $options['CURLOPT_HTTPHEADER'] = array(
579
                 'Content-Type: '.$contenttype,
580
                 'Content-Length: '.strlen($data),
581
                 'Content-Language: en-US',
582
               );
583
584
        return $c->post($url, $data, $options);
585
    }
586
    return $c->get($url);
587
}
588
589
/**
590
 * End the session associated with this instance (if it's running).
591
 *
592
 * @param object $bigbluebuttonbn
593
 *
594
 * @return void
595
 */
596
function bigbluebuttonbn_end_meeting_if_running($bigbluebuttonbn) {
597
    $meetingid = $bigbluebuttonbn->meetingid.'-'.$bigbluebuttonbn->course.'-'.$bigbluebuttonbn->id;
598
    if (bigbluebuttonbn_is_meeting_running($meetingid)) {
599
        bigbluebuttonbn_end_meeting($meetingid, $bigbluebuttonbn->moderatorpass);
600
    }
601
}
602
603
/**
604
 * Returns user roles in a context.
605
 *
606
 * @param context $context
607
 * @param context $userid
608
 *
609
 * @return array $userroles
610
 */
611
function bigbluebuttonbn_get_user_roles($context, $userid) {
612
    global $DB;
613
    $userroles = get_user_roles($context, $userid);
614
    if ($userroles) {
615
        $where = '';
616
        foreach ($userroles as $userrole) {
617
            $where .= (empty($where) ? ' WHERE' : ' OR').' id='.$userrole->roleid;
618
        }
619
        $userroles = $DB->get_records_sql('SELECT * FROM {role}'.$where);
620
    }
621
    return $userroles;
622
}
623
624
/**
625
 * Returns guest role wrapped in an array.
626
 *
627
 * @return array
628
 */
629
function bigbluebuttonbn_get_guest_role() {
630
    $guestrole = get_guest_role();
631
    return array($guestrole->id => $guestrole);
632
}
633
634
/**
635
 * Returns an array containing all the users in a context.
636
 *
637
 * @param context $context
638
 *
639
 * @return array $users
640
 */
641
function bigbluebuttonbn_get_users(context $context = null) {
642
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
643
    foreach ($users as $key => $value) {
644
        $users[$key] = fullname($value);
645
    }
646
    return $users;
647
}
648
649
/**
650
 * Returns an array containing all the users in a context wrapped for html select element.
651
 *
652
 * @param context $context
653
 *
654
 * @return array $users
655
 */
656
function bigbluebuttonbn_get_users_select(context $context = null) {
657
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
658
    foreach ($users as $key => $value) {
659
        $users[$key] = array('id' => $value->id, 'name' => fullname($value));
660
    }
661
    return $users;
662
}
663
664
/**
665
 * Returns an array containing all the roles in a context.
666
 *
667
 * @param context $context
668
 *
669
 * @return array $roles
670
 */
671
function bigbluebuttonbn_get_roles(context $context = null) {
672
    $roles = (array) role_get_names($context);
673
    foreach ($roles as $key => $value) {
674
        $roles[$key] = $value->localname;
675
    }
676
    return $roles;
677
}
678
679
/**
680
 * Returns an array containing all the roles in a context wrapped for html select element.
681
 *
682
 * @param context $context
683
 *
684
 * @return array $users
685
 */
686
function bigbluebuttonbn_get_roles_select(context $context = null) {
687
    $roles = (array) role_get_names($context);
688
    foreach ($roles as $key => $value) {
689
        $roles[$key] = array('id' => $value->id, 'name' => $value->localname);
690
    }
691
    return $roles;
692
}
693
694
/**
695
 * Returns role that corresponds to an id.
696
 *
697
 * @param string|integer $id
698
 *
699
 * @return object $role
700
 */
701
function bigbluebuttonbn_get_role($id) {
702
    $roles = (array) role_get_names();
703
    if (is_numeric($id)) {
704
        return (object)$roles[$id];
705
    }
706
    foreach ($roles as $role) {
707
        if ($role->shortname == $id) {
708
            return $role;
709
        }
710
    }
711
}
712
713
/**
714
 * Returns an array to populate a list of participants used in mod_form.js.
715
 *
716
 * @param context $context
717
 *
718
 * @return array $data
719
 */
720
function bigbluebuttonbn_get_participant_data($context) {
721
    $data = array(
722
        'all' => array(
723
            'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
724
            'children' => []
725
          )
726
      );
727
    $data['role'] = array(
728
        'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
729
        'children' => bigbluebuttonbn_get_roles_select($context)
730
      );
731
    $data['user'] = array(
732
        'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
733
        'children' => bigbluebuttonbn_get_users_select($context)
734
      );
735
    return $data;
736
}
737
738
/**
739
 * Returns an array to populate a list of participants used in mod_form.php.
740
 *
741
 * @param object $bigbluebuttonbn
742
 * @param context $context
743
 *
744
 * @return array
745
 */
746
function bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context) {
747
    if ($bigbluebuttonbn == null) {
748
        return bigbluebuttonbn_get_participant_list_default($context);
749
    }
750
    return bigbluebuttonbn_get_participant_rules_encoded($bigbluebuttonbn);
751
}
752
753
/**
754
 * Returns an array to populate a list of participants used in mod_form.php with default values.
755
 *
756
 * @param context $context
757
 *
758
 * @return array
759
 */
760
function bigbluebuttonbn_get_participant_list_default($context) {
761
    global $USER;
762
    $participantlistarray = array();
763
    $participantlistarray[] = array(
764
        'selectiontype' => 'all',
765
        'selectionid' => 'all',
766
        'role' => BIGBLUEBUTTONBN_ROLE_VIEWER);
767
    $moderatordefaults = explode(',', \mod_bigbluebuttonbn\locallib\config::get('participant_moderator_default'));
768
    foreach ($moderatordefaults as $moderatordefault) {
769
        if ($moderatordefault == '0') {
770
            if (is_enrolled($context, $USER->id)) {
771
                $participantlistarray[] = array(
772
                    'selectiontype' => 'user',
773
                    'selectionid' => $USER->id,
774
                    'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
775
            }
776
            continue;
777
        }
778
        $participantlistarray[] = array(
779
              'selectiontype' => 'role',
780
              'selectionid' => $moderatordefault,
781
              'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
782
    }
783
    return $participantlistarray;
784
}
785
786
/**
787
 * Returns an array to populate a list of participants used in mod_form.php with bigbluebuttonbn values.
788
 *
789
 * @param object $bigbluebuttonbn
790
 *
791
 * @return array
792
 */
793
function bigbluebuttonbn_get_participant_rules_encoded($bigbluebuttonbn) {
794
    $rules = json_decode($bigbluebuttonbn->participants, true);
795
    if (!is_array($rules)) {
796
        return array();
797
    }
798
    foreach ($rules as $key => $rule) {
799
        if ( $rule['selectiontype'] !== 'role' || is_numeric($rule['selectionid']) ) {
800
            continue;
801
        }
802
        $role = bigbluebuttonbn_get_role($rule['selectionid']);
803
        if ( $role == null ) {
804
            unset($rules[$key]);
805
            continue;
806
        }
807
        $rule['selectionid'] = $role->id;
808
        $rules[$key] = $rule;
809
    }
810
    return $rules;
811
}
812
813
/**
814
 * Returns an array to populate a list of participant_selection used in mod_form.php.
815
 *
816
 * @return array
817
 */
818
function bigbluebuttonbn_get_participant_selection_data() {
819
    return [
820
        'type_options' => [
821
            'all' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
822
            'role' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
823
            'user' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
824
          ],
825
        'type_selected' => 'all',
826
        'options' => ['all' => '---------------'],
827
        'selected' => 'all',
828
      ];
829
}
830
831
/**
832
 * Evaluate if a user in a context is moderator based on roles and participation rules.
833
 *
834
 * @param context $context
835
 * @param string $participants
836
 * @param integer $userid
837
 * @param array $userroles
838
 *
839
 * @return boolean
840
 */
841
function bigbluebuttonbn_is_moderator($context, $participants, $userid = null, $userroles = null) {
842
    global $USER;
843
    if (empty($participants)) {
844
        // The room that is being used comes from a previous version.
845
        return has_capability('mod/bigbluebuttonbn:moderate', $context);
846
    }
847
    $participantlist = json_decode($participants);
848
    if (!is_array($participantlist)) {
849
        return false;
850
    }
851
    if (empty($userid)) {
852
        $userid = $USER->id;
853
    }
854
    if (empty($userroles)) {
855
        $userroles = get_user_roles($context, $userid, true);
856
    }
857
    return bigbluebuttonbn_is_moderator_validator($participantlist, $userid , $userroles);
858
}
859
860
/**
861
 * Iterates participant list rules to evaluate if a user is moderator.
862
 *
863
 * @param array $participantlist
864
 * @param integer $userid
865
 * @param array $userroles
866
 *
867
 * @return boolean
868
 */
869
function bigbluebuttonbn_is_moderator_validator($participantlist, $userid, $userroles) {
870
    // Iterate participant rules.
871
    foreach ($participantlist as $participant) {
872
        if (bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles)) {
873
            return true;
874
        }
875
    }
876
    return false;
877
}
878
879
/**
880
 * Evaluate if a user is moderator based on roles and a particular participation rule.
881
 *
882
 * @param object $participant
883
 * @param integer $userid
884
 * @param array $userroles
885
 *
886
 * @return boolean
887
 */
888
function bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles) {
889
    if ($participant->role == BIGBLUEBUTTONBN_ROLE_VIEWER) {
890
        return false;
891
    }
892
    // Looks for all configuration.
893
    if ($participant->selectiontype == 'all') {
894
        return true;
895
    }
896
    // Looks for users.
897
    if ($participant->selectiontype == 'user' && $participant->selectionid == $userid) {
898
        return true;
899
    }
900
    // Looks for roles.
901
    $role = bigbluebuttonbn_get_role($participant->selectionid);
902
    if (array_key_exists($role->id, $userroles)) {
903
        return true;
904
    }
905
    return false;
906
}
907
908
/**
909
 * Helper returns error message key for the language file that corresponds to a bigbluebutton error key.
910
 *
911
 * @param string $messagekey
912
 * @param string $defaultkey
913
 *
914
 * @return string
915
 */
916
function bigbluebuttonbn_get_error_key($messagekey, $defaultkey = null) {
917
    if ($messagekey == 'checksumError') {
918
        return 'index_error_checksum';
919
    }
920
    if ($messagekey == 'maxConcurrent') {
921
        return 'view_error_max_concurrent';
922
    }
923
    return $defaultkey;
924
}
925
926
/**
927
 * Helper evaluates if a voicebridge number is unique.
928
 *
929
 * @param integer $voicebridge
930
 *
931
 * @return string
932
 */
933
function bigbluebuttonbn_voicebridge_unique($voicebridge) {
934
    global $DB;
935
    if ($voicebridge != 0) {
936
        $table = 'bigbluebuttonbn';
937
        $select = 'voicebridge = '.$voicebridge;
938
        if ($DB->get_records_select($table, $select)) {
939
            return false;
940
        }
941
    }
942
    return true;
943
}
944
945
/**
946
 * Helper estimate a duration for the meeting based on the closingtime.
947
 *
948
 * @param integer $closingtime
949
 *
950
 * @return integer
951
 */
952
function bigbluebuttonbn_get_duration($closingtime) {
953
    $duration = 0;
954
    $now = time();
955
    if ($closingtime > 0 && $now < $closingtime) {
956
        $duration = ceil(($closingtime - $now) / 60);
957
        $compensationtime = intval((int)\mod_bigbluebuttonbn\locallib\config::get('scheduled_duration_compensation'));
958
        $duration = intval($duration) + $compensationtime;
959
    }
960
    return $duration;
961
}
962
963
/**
964
 * Helper return array containing the file descriptor for a preuploaded presentation.
965
 *
966
 * @param context $context
967
 * @param string $presentation
968
 * @param integer $id
969
 *
970
 * @return array
971
 */
972
function bigbluebuttonbn_get_presentation_array($context, $presentation, $id = null) {
973
    if (empty($presentation)) {
974
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
975
    }
976
    $fs = get_file_storage();
977
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
978
        'itemid, filepath, filename', false);
979
    if (count($files) == 0) {
980
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
981
    }
982
    $file = reset($files);
983
    unset($files);
984
    $pnoncevalue = null;
985
    if (!is_null($id)) {
986
        // Create the nonce component for granting a temporary public access.
987
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn',
988
            'presentation_cache');
989
        $pnoncekey = sha1($id);
990
        /* The item id was adapted for granting public access to the presentation once in order
991
         * to allow BigBlueButton to gather the file. */
992
        $pnoncevalue = bigbluebuttonbn_generate_nonce();
993
        $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
994
    }
995
    $url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
996
        $file->get_filearea(), $pnoncevalue, $file->get_filepath(), $file->get_filename());
997
    return array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
998
            'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file));
999
}
1000
1001
/**
1002
 * Helper generates a nonce used for the preuploaded presentation callback url.
1003
 *
1004
 * @return string
1005
 */
1006
function bigbluebuttonbn_generate_nonce() {
1007
    $mt = microtime();
1008
    $rand = mt_rand();
1009
    return md5($mt.$rand);
1010
}
1011
1012
/**
1013
 * Helper generates a random password.
1014
 *
1015
 * @param integer $length
1016
 * @param string $unique
1017
 *
1018
 * @return string
1019
 */
1020
function bigbluebuttonbn_random_password($length = 8, $unique = "") {
1021
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?';
1022
    do {
1023
        $password = substr(str_shuffle($chars), 0, $length);
1024
    } while ($unique == $password);
1025
    return $password;
1026
}
1027
1028
/**
1029
 * Helper returns an array with all possible bigbluebuttonbn events.
1030
 *
1031
 * @return array
1032
 */
1033
function bigbluebuttonbn_events() {
1034
    return array(
1035
        (string) BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED,
1036
        (string) BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED,
1037
        (string) BIGBLUEBUTTON_EVENT_LIVE_SESSION,
1038
        (string) BIGBLUEBUTTON_EVENT_MEETING_CREATED,
1039
        (string) BIGBLUEBUTTON_EVENT_MEETING_ENDED,
1040
        (string) BIGBLUEBUTTON_EVENT_MEETING_JOINED,
1041
        (string) BIGBLUEBUTTON_EVENT_MEETING_LEFT,
1042
        (string) BIGBLUEBUTTON_EVENT_RECORDING_DELETED,
1043
        (string) BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED,
1044
        (string) BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED,
1045
        (string) BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED,
1046
        (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED,
1047
        (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED,
1048
        (string) BIGBLUEBUTTON_EVENT_RECORDING_EDITED,
1049
        (string) BIGBLUEBUTTON_EVENT_RECORDING_VIEWED
1050
    );
1051
}
1052
1053
/**
1054
 * Helper returns an array with the actions and their corresponding bigbluebuttonbn events.
1055
 *
1056
 * @return array
1057
 */
1058
function bigbluebuttonbn_events_action() {
1059
    return array(
1060
        'view' => (string) BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED,
1061
        'view_management' => (string) BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED,
1062
        'live_action' => (string) BIGBLUEBUTTON_EVENT_LIVE_SESSION,
1063
        'meeting_create' => (string) BIGBLUEBUTTON_EVENT_MEETING_CREATED,
1064
        'meeting_end' => (string) BIGBLUEBUTTON_EVENT_MEETING_ENDED,
1065
        'meeting_join' => (string) BIGBLUEBUTTON_EVENT_MEETING_JOINED,
1066
        'meeting_left' => (string) BIGBLUEBUTTON_EVENT_MEETING_LEFT,
1067
        'recording_delete' => (string) BIGBLUEBUTTON_EVENT_RECORDING_DELETED,
1068
        'recording_import' => (string) BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED,
1069
        'recording_protect' => (string) BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED,
1070
        'recording_publish' => (string) BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED,
1071
        'recording_unprotect' => (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED,
1072
        'recording_unpublish' => (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED,
1073
        'recording_edit' => (string) BIGBLUEBUTTON_EVENT_RECORDING_EDITED,
1074
        'recording_play' => (string) BIGBLUEBUTTON_EVENT_RECORDING_VIEWED
1075
    );
1076
}
1077
1078
/**
1079
 * Helper register a bigbluebuttonbn event.
1080
 *
1081
 * @param string $eventtype
1082
 * @param object $bigbluebuttonbn
1083
 * @param object $cm
1084
 * @param array $options
1085
 *
1086
 * @return void
1087
 */
1088
function bigbluebuttonbn_event_log($eventtype, $bigbluebuttonbn, $cm, $options = []) {
1089
    $events = bigbluebuttonbn_events();
1090
    if (!in_array($eventtype, $events)) {
1091
        // No log will be created.
1092
        return;
1093
    }
1094
    $context = context_module::instance($cm->id);
1095
    $eventproperties = array('context' => $context, 'objectid' => $bigbluebuttonbn->id);
1096
    if (array_key_exists('timecreated', $options)) {
1097
        $eventproperties['timecreated'] = $options['timecreated'];
1098
    }
1099
    if (array_key_exists('userid', $options)) {
1100
        $eventproperties['userid'] = $options['userid'];
1101
    }
1102
    if (array_key_exists('other', $options)) {
1103
        $eventproperties['other'] = $options['other'];
1104
    }
1105
    $event = call_user_func_array('\mod_bigbluebuttonbn\event\bigbluebuttonbn_'.$eventtype.'::create',
1106
      array($eventproperties));
1107
    $event->trigger();
1108
}
1109
1110
/**
1111
 * Updates the meeting info cached object when a participant has joined.
1112
 *
1113
 * @param string $meetingid
1114
 * @param bool $ismoderator
1115
 *
1116
 * @return void
1117
 */
1118
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) {
1119
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1120
    $result = $cache->get($meetingid);
1121
    $meetinginfo = json_decode($result['meeting_info']);
1122
    $meetinginfo->participantCount += 1;
1123
    if ($ismoderator) {
1124
        $meetinginfo->moderatorCount += 1;
1125
    }
1126
    $cache->set($meetingid, array('creation_time' => $result['creation_time'],
1127
        'meeting_info' => json_encode($meetinginfo)));
1128
}
1129
1130
/**
1131
 * Gets a meeting info object cached or fetched from the live session.
1132
 *
1133
 * @param string $meetingid
1134
 * @param boolean $updatecache
1135
 *
1136
 * @return array
1137
 */
1138
function bigbluebuttonbn_get_meeting_info($meetingid, $updatecache = false) {
1139
    $cachettl = (int)\mod_bigbluebuttonbn\locallib\config::get('waitformoderator_cache_ttl');
1140
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1141
    $result = $cache->get($meetingid);
1142
    $now = time();
1143
    if (!$updatecache && isset($result) && $now < ($result['creation_time'] + $cachettl)) {
1144
        // Use the value in the cache.
1145
        return (array) json_decode($result['meeting_info']);
1146
    }
1147
    // Ping again and refresh the cache.
1148
    $meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file(
1149
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
1150
      );
1151
    $cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo)));
1152
    return $meetinginfo;
1153
}
1154
1155
/**
1156
 * Publish an imported recording.
1157
 *
1158
 * @param string $id
1159
 * @param boolean $publish
1160
 *
1161
 * @return boolean
1162
 */
1163 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...
1164
    global $DB;
1165
    // Locate the record to be updated.
1166
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1167
    $meta = json_decode($record->meta, true);
1168
    // Prepare data for the update.
1169
    $meta['recording']['published'] = ($publish) ? 'true' : 'false';
1170
    $record->meta = json_encode($meta);
1171
    // Proceed with the update.
1172
    $DB->update_record('bigbluebuttonbn_logs', $record);
1173
    return true;
1174
}
1175
1176
/**
1177
 * Delete an imported recording.
1178
 *
1179
 * @param string $id
1180
 *
1181
 * @return boolean
1182
 */
1183
function bigbluebuttonbn_delete_recording_imported($id) {
1184
    global $DB;
1185
    // Execute delete.
1186
    $DB->delete_records('bigbluebuttonbn_logs', array('id' => $id));
1187
    return true;
1188
}
1189
1190
/**
1191
 * Update an imported recording.
1192
 *
1193
 * @param string $id
1194
 * @param array $params ['key'=>param_key, 'value']
1195
 *
1196
 * @return boolean
1197
 */
1198
function bigbluebuttonbn_update_recording_imported($id, $params) {
1199
    global $DB;
1200
    // Locate the record to be updated.
1201
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1202
    $meta = json_decode($record->meta, true);
1203
    // Prepare data for the update.
1204
    $meta['recording'] = $params + $meta['recording'];
1205
    $record->meta = json_encode($meta);
1206
    // Proceed with the update.
1207
    if (!$DB->update_record('bigbluebuttonbn_logs', $record)) {
1208
        return false;
1209
    }
1210
    return true;
1211
}
1212
1213
/**
1214
 * Protect/Unprotect an imported recording.
1215
 *
1216
 * @param string $id
1217
 * @param boolean $protect
1218
 *
1219
 * @return boolean
1220
 */
1221 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...
1222
    global $DB;
1223
    // Locate the record to be updated.
1224
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1225
    $meta = json_decode($record->meta, true);
1226
    // Prepare data for the update.
1227
    $meta['recording']['protected'] = ($protect) ? 'true' : 'false';
1228
    $record->meta = json_encode($meta);
1229
    // Proceed with the update.
1230
    $DB->update_record('bigbluebuttonbn_logs', $record);
1231
    return true;
1232
}
1233
1234
/**
1235
 * Sets a custom config.xml file for being used on create.
1236
 *
1237
 * @param string $meetingid
1238
 * @param string $configxml
1239
 *
1240
 * @return object
1241
 */
1242
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) {
1243
    $urldefaultconfig = \mod_bigbluebuttonbn\locallib\config::get('server_url').'api/setConfigXML?';
1244
    $configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml);
1245
    $xml = bigbluebuttonbn_wrap_xml_load_file($urldefaultconfig, 'POST',
1246
        $configxmlparams, 'application/x-www-form-urlencoded');
1247
    return $xml;
1248
}
1249
1250
/**
1251
 * Sets qs used with a custom config.xml file request.
1252
 *
1253
 * @param string $meetingid
1254
 * @param string $configxml
1255
 *
1256
 * @return string
1257
 */
1258
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) {
1259
    $params = 'configXML='.urlencode($configxml).'&meetingID='.urlencode($meetingid);
1260
    $configxmlparams = $params.'&checksum='.sha1('setConfigXML'.$params.\mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
1261
    return $configxmlparams;
1262
}
1263
1264
/**
1265
 * Sets a custom config.xml file for being used on create.
1266
 *
1267
 * @param string $meetingid
1268
 * @param string $configxml
1269
 *
1270
 * @return array
1271
 */
1272
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) {
1273
    $configxml = bigbluebuttonbn_setConfigXML($meetingid, $configxml);
1274
    $configxmlarray = (array) $configxml;
1275
    if ($configxmlarray['returncode'] != 'SUCCESS') {
1276
        debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER);
1277
        return '';
1278
    }
1279
    return $configxmlarray['configToken'];
1280
}
1281
1282
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['protect', 'publish', 'delete']) {
1283
    if (!$bbbsession['managerecordings'] && $recording['published'] != 'true') {
1284
        return;
1285
    }
1286
    $editable = bigbluebuttonbn_get_recording_data_row_editable($bbbsession);
1287
    $row = new stdClass();
1288
    // Set recording_types.
1289
    $row->recording = bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession['bigbluebuttonbn']->id);
1290
    // Set activity name.
1291
    $row->activity = bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $editable);
1292
    // Set activity description.
1293
    $row->description = bigbluebuttonbn_get_recording_data_row_meta_description($recording, $editable);
1294
    // Set recording_preview.
1295
    $row->preview = bigbluebuttonbn_get_recording_data_row_preview($recording);
1296
    // Set date.
1297
    $row->date = bigbluebuttonbn_get_recording_data_row_date($recording);
1298
    // Set formatted date.
1299
    $row->date_formatted = bigbluebuttonbn_get_recording_data_row_date_formatted($row->date);
1300
    // Set formatted duration.
1301
    $row->duration_formatted = $row->duration = bigbluebuttonbn_get_recording_data_row_duration($recording);
1302
    // Set actionbar, if user is allowed to manage recordings.
1303
    if ($bbbsession['managerecordings']) {
1304
        $row->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools);
1305
    }
1306
    return $row;
1307
}
1308
1309
function bigbluebuttonbn_get_recording_data_row_editable($bbbsession) {
1310
    return ($bbbsession['managerecordings'] && ((double)$bbbsession['serverversion'] >= 1.0 || bigbluebuttonbn_is_bn_server()));
1311
}
1312
1313
function bigbluebuttonbn_get_recording_data_row_date($recording) {
1314
    if (!isset($recording['startTime'])) {
1315
        return 0;
1316
    }
1317
    return floatval($recording['startTime']);
1318
}
1319
1320
function bigbluebuttonbn_get_recording_data_row_date_formatted($starttime) {
1321
    global $USER;
1322
    $starttime = $starttime - ($starttime % 1000);
1323
    // Set formatted date.
1324
    $dateformat = get_string('strftimerecentfull', 'langconfig').' %Z';
1325
    return userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone));
1326
}
1327
1328
function bigbluebuttonbn_get_recording_data_row_duration($recording) {
1329
    $firstplayback = array_values($recording['playbacks'])[0];
1330
    $length = 0;
1331
    if (isset($firstplayback['length'])) {
1332
        $length = $firstplayback['length'];
1333
    }
1334
    return intval($length);
1335
}
1336
1337
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) {
1338
    $actionbar = '';
1339
    foreach ($tools as $tool) {
1340
        if ( $tool == 'protect' && !isset($recording['protected']) ) {
1341
            continue;
1342
        }
1343
        $buttonpayload = bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool);
1344
        $actionbar .= bigbluebuttonbn_actionbar_render_button($recording, $buttonpayload);
1345
    }
1346
    $head = html_writer::start_tag('div', array(
1347
        'id' => 'recording-actionbar-' . $recording['recordID'],
1348
        'data-recordingid' => $recording['recordID'],
1349
        'data-meetingid' => $recording['meetingID']));
1350
    $tail = html_writer::end_tag('div');
1351
    return $head . $actionbar . $tail;
1352
}
1353
1354
function bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool) {
1355
    if ($tool == 'protect') {
1356
        return bigbluebuttonbn_get_recording_data_row_action_protect($recording['protected']);
1357
    }
1358
    if ($tool == 'publish') {
1359
        return bigbluebuttonbn_get_recording_data_row_action_publish($recording['published']);
1360
    }
1361
    return array('action' => $tool, 'tag' => $tool);
1362
}
1363
1364
function bigbluebuttonbn_get_recording_data_row_action_protect($protected) {
1365
    if ($protected == 'true') {
1366
        return array('action' => 'unprotect', 'tag' => 'lock');
1367
    }
1368
    return array('action' => 'protect', 'tag' => 'unlock');
1369
}
1370
1371
function bigbluebuttonbn_get_recording_data_row_action_publish($published) {
1372
    if ($published == 'true') {
1373
        return array('action' => 'unpublish', 'tag' => 'hide');
1374
    }
1375
    return array('action' => 'publish', 'tag' => 'show');
1376
}
1377
1378
function bigbluebuttonbn_get_recording_data_row_preview($recording) {
1379
    $visibility = '';
1380
    if ($recording['published'] === 'false') {
1381
        $visibility = 'hidden ';
1382
    }
1383
    $recordingpreview = html_writer::start_tag('div',
1384
        array('id' => 'preview-'.$recording['recordID'], $visibility => $visibility));
1385
    foreach ($recording['playbacks'] as $playback) {
1386
        if (isset($playback['preview'])) {
1387
            foreach ($playback['preview'] as $image) {
1388
                $recordingpreview .= html_writer::empty_tag('img',
1389
                    array('src' => trim($image['url']) . '?' . time(), 'class' => 'thumbnail'));
1390
            }
1391
            $recordingpreview .= html_writer::empty_tag('br');
1392
            $recordingpreview .= html_writer::tag('div',
1393
                get_string('view_recording_preview_help', 'bigbluebuttonbn'), array('class' => 'text-muted small'));
1394
            break;
1395
        }
1396
    }
1397
    $recordingpreview .= html_writer::end_tag('div');
1398
    return $recordingpreview;
1399
}
1400
1401
function bigbluebuttonbn_get_recording_data_row_types($recording, $bigbluebuttonbnid) {
1402
    $dataimported = 'false';
1403
    $title = '';
1404
    if (isset($recording['imported'])) {
1405
        $dataimported = 'true';
1406
        $title = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1407
    }
1408
    $visibility = '';
1409
    if ($recording['published'] === 'false') {
1410
        $visibility = 'hidden ';
1411
    }
1412
    $id = 'playbacks-'.$recording['recordID'];
1413
    $recordingtypes = html_writer::start_tag('div', array('id' => $id, 'data-imported' => $dataimported,
1414
          'data-meetingid' => $recording['meetingID'], 'data-recordingid' => $recording['recordID'],
1415
          'title' => $title, $visibility => $visibility));
1416
    foreach ($recording['playbacks'] as $playback) {
1417
        $recordingtypes .= bigbluebuttonbn_get_recording_data_row_type($recording, $bigbluebuttonbnid,
1418
            $playback).'&#32;';
1419
    }
1420
    $recordingtypes .= html_writer::end_tag('div');
1421
    return $recordingtypes;
1422
}
1423
1424
function bigbluebuttonbn_get_recording_data_row_type($recording, $bigbluebuttonbnid, $playback) {
1425
    global $CFG, $OUTPUT;
1426
    $title = get_string('view_recording_format_'.$playback['type'], 'bigbluebuttonbn');
1427
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recordingPlay(this);';
1428
    $href = $CFG->wwwroot.'/mod/bigbluebuttonbn/bbb_view.php?action=play&bn='.$bigbluebuttonbnid.
1429
      '&mid='.$recording['meetingID'].'&rid='.$recording['recordID'].'&rtype='.$playback['type'];
1430
    if (!isset($recording['imported']) || !isset($recording['protected']) || $recording['protected'] === 'false') {
1431
        $href .= '&href='.urlencode(trim($playback['url']));
1432
    }
1433
    $id = 'recording-play-' . $playback['type'] . '-' . $recording['recordID'];
1434
    $linkattributes = array(
1435
        'id' => $id,
1436
        'onclick' => $onclick,
1437
        'data-action' => 'play',
1438
        'data-target' => $playback['type'],
1439
        'data-href' => $href,
1440
        'class' => 'btn btn-sm btn-default'
1441
      );
1442
    return $OUTPUT->action_link('#', $title, null, $linkattributes);
1443
}
1444
1445
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $editable) {
1446
    $payload = array();
1447 View Code Duplication
    if ($editable) {
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...
1448
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1449
            'action' => 'edit', 'tag' => 'edit',
1450
            'target' => 'name');
1451
    }
1452
    $oldsource = 'meta_contextactivity';
1453 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...
1454
        $metaname = trim($recording[$oldsource]);
1455
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $oldsource, $payload);
1456
    }
1457
    $newsource = 'meta_bbb-recording-name';
1458 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...
1459
        $metaname = trim($recording[$newsource]);
1460
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1461
    }
1462
    $metaname = trim($recording['meetingName']);
1463
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1464
}
1465
1466
function bigbluebuttonbn_get_recording_data_row_meta_description($recording, $editable) {
1467
    $payload = array();
1468 View Code Duplication
    if ($editable) {
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...
1469
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1470
            'action' => 'edit', 'tag' => 'edit',
1471
            'target' => 'description');
1472
    }
1473
    $oldsource = 'meta_contextactivitydescription';
1474 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...
1475
        $metadescription = trim($recording[$oldsource]);
1476
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $oldsource, $payload);
1477
    }
1478
    $newsource = 'meta_bbb-recording-description';
1479
    if (isset($recording[$newsource])) {
1480
        $metadescription = trim($recording[$newsource]);
1481
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $newsource, $payload);
1482
    }
1483
    return bigbluebuttonbn_get_recording_data_row_text($recording, '', $newsource, $payload);
1484
}
1485
1486
function bigbluebuttonbn_get_recording_data_row_text($recording, $text, $source, $data) {
1487
    $htmltext = '<span>' . htmlentities($text) . '</span>';
1488
    if (empty($data)) {
1489
        return $htmltext;
1490
    }
1491
    $target = $data['action'] . '-' . $data['target'];
1492
    $id = 'recording-' . $target . '-' . $data['recordingid'];
1493
    $attributes = array('id' => $id, 'class' => 'quickeditlink col-md-20',
1494
        'data-recordingid' => $data['recordingid'], 'data-meetingid' => $data['meetingid'],
1495
        'data-target' => $data['target'], 'data-source' => $source);
1496
    $head = html_writer::start_tag('div', $attributes);
1497
    $tail = html_writer::end_tag('div');
1498
    $payload = array('action' => $data['action'], 'tag' => $data['tag'], 'target' => $data['target']);
1499
    $htmllink = bigbluebuttonbn_actionbar_render_button($recording, $payload);
1500
    return $head . $htmltext . $htmllink . $tail;
1501
}
1502
1503
function bigbluebuttonbn_actionbar_render_button($recording, $data) {
1504
    global $OUTPUT;
1505
    if (!$data) {
1506
        return '';
1507
    }
1508
    $target = $data['action'];
1509
    if (isset($data['target'])) {
1510
        $target .= '-' . $data['target'];
1511
    }
1512
    $id = 'recording-' . $target . '-' . $recording['recordID'];
1513
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recording' . ucfirst($data['action']) . '(this);';
1514
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::get('recording_icons_enabled')) {
1515
        // With icon for $manageaction.
1516
        $iconattributes = array('id' => $id, 'class' => 'iconsmall');
1517
        $icon = new pix_icon('i/'.$data['tag'],
1518
            get_string('view_recording_list_actionbar_' . $data['action'], 'bigbluebuttonbn'),
1519
            'moodle', $iconattributes);
1520
        $linkattributes = array(
1521
            'id' => $id,
1522
            'onclick' => $onclick,
1523
            'data-action' => $data['action'],
1524
            'data-links' => bigbluebuttonbn_get_count_recording_imported_instances($recording['recordID'])
1525
          );
1526
        return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false);
1527
    }
1528
    // With text for $manageaction.
1529
    $linkattributes = array('title' => get_string($data['tag']), 'class' => 'btn btn-xs btn-danger',
1530
        'onclick' => $onclick);
1531
    return $OUTPUT->action_link('#', get_string($data['action']), null, $linkattributes);
1532
}
1533
1534
function bigbluebuttonbn_get_recording_columns($bbbsession) {
1535
    // Set strings to show.
1536
    $recording = get_string('view_recording_recording', 'bigbluebuttonbn');
1537
    $activity = get_string('view_recording_activity', 'bigbluebuttonbn');
1538
    $description = get_string('view_recording_description', 'bigbluebuttonbn');
1539
    $preview = get_string('view_recording_preview', 'bigbluebuttonbn');
1540
    $date = get_string('view_recording_date', 'bigbluebuttonbn');
1541
    $duration = get_string('view_recording_duration', 'bigbluebuttonbn');
1542
    $actionbar = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1543
    // Initialize table headers.
1544
    $recordingsbncolumns = array(
1545
        array('key' => 'recording', 'label' => $recording, 'width' => '125px', 'allowHTML' => true),
1546
        array('key' => 'activity', 'label' => $activity, 'sortable' => true, 'width' => '175px', 'allowHTML' => true),
1547
        array('key' => 'description', 'label' => $description, 'sortable' => true, 'width' => '250px', 'allowHTML' => true),
1548
        array('key' => 'preview', 'label' => $preview, 'width' => '250px', 'allowHTML' => true),
1549
        array('key' => 'date', 'label' => $date, 'sortable' => true, 'width' => '225px', 'allowHTML' => true),
1550
        array('key' => 'duration', 'label' => $duration, 'width' => '50px'),
1551
        );
1552
    if ($bbbsession['managerecordings']) {
1553
        array_push($recordingsbncolumns, array('key' => 'actionbar', 'label' => $actionbar, 'width' => '120px',
1554
            'allowHTML' => true));
1555
    }
1556
    return $recordingsbncolumns;
1557
}
1558
1559
function bigbluebuttonbn_get_recording_data($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1560
    $tabledata = array();
1561
    // Build table content.
1562 View Code Duplication
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
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...
1563
        // There are recordings for this meeting.
1564
        foreach ($recordings as $recording) {
1565
            $row = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1566
            if ($row != null) {
1567
                array_push($tabledata, $row);
1568
            }
1569
        }
1570
    }
1571
    return $tabledata;
1572
}
1573
1574
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1575
    // Set strings to show.
1576
    $recording = get_string('view_recording_recording', 'bigbluebuttonbn');
1577
    $description = get_string('view_recording_description', 'bigbluebuttonbn');
1578
    $date = get_string('view_recording_date', 'bigbluebuttonbn');
1579
    $duration = get_string('view_recording_duration', 'bigbluebuttonbn');
1580
    $actionbar = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1581
    $playback = get_string('view_recording_playback', 'bigbluebuttonbn');
1582
    $preview = get_string('view_recording_preview', 'bigbluebuttonbn');
1583
    // Declare the table.
1584
    $table = new html_table();
1585
    $table->data = array();
1586
    // Initialize table headers.
1587
    $table->head = array($playback, $recording, $description, $preview, $date, $duration);
1588
    $table->align = array('left', 'left', 'left', 'left', 'left', 'center');
1589
    $table->size = array('', '', '', '', '', '');
1590
    if ($bbbsession['managerecordings']) {
1591
        $table->head[] = $actionbar;
1592
        $table->align[] = 'left';
1593
        $table->size[] = (count($tools) * 40) . 'px';
1594
    }
1595
    // Build table content.
1596 View Code Duplication
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
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...
1597
        // There are recordings for this meeting.
1598
        foreach ($recordings as $recording) {
1599
            if ( !bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) ) {
1600
                continue;
1601
            }
1602
            bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $tools, $table);
1603
        }
1604
    }
1605
    return $table;
1606
}
1607
1608
function bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $tools, &$table) {
1609
    $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1610
    if ($rowdata == null) {
1611
        return;
1612
    }
1613
    $row = new html_table_row();
1614
    $row->id = 'recording-td-'.$recording['recordID'];
1615
    $row->attributes['data-imported'] = 'false';
1616
    $texthead = '';
1617
    $texttail = '';
1618
    if (isset($recording['imported'])) {
1619
        $row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1620
        $row->attributes['data-imported'] = 'true';
1621
        $texthead = '<em>';
1622
        $texttail = '</em>';
1623
    }
1624
    $rowdata->date_formatted = str_replace(' ', '&nbsp;', $rowdata->date_formatted);
1625
    $row->cells = array(
1626
        $texthead . $rowdata->recording . $texttail,
1627
        $texthead . $rowdata->activity . $texttail, $texthead . $rowdata->description . $texttail,
1628
        $rowdata->preview, $texthead . $rowdata->date_formatted . $texttail,
1629
        $rowdata->duration_formatted
1630
      );
1631
    if ($bbbsession['managerecordings']) {
1632
        $row->cells[] = $rowdata->actionbar;
1633
    }
1634
    array_push($table->data, $row);
1635
}
1636
1637
function bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) {
1638
    if ( isset($recording['imported']) || !isset($bbbsession['group']) || $recording['meetingID'] == $bbbsession['meetingid'] ) {
1639
        return true;
1640
    }
1641
    return false;
1642
}
1643
1644
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) {
1645
    $sender = get_admin();
1646
    // Prepare message.
1647
    $msg = new stdClass();
1648
    // Build the message_body.
1649
    $msg->activity_type = '';
1650
    $msg->activity_title = $bigbluebuttonbn->name;
1651
    $messagetext = '<p>'.get_string('email_body_recording_ready_for', 'bigbluebuttonbn').' '.
1652
        $msg->activity_type.' &quot;'.$msg->activity_title.'&quot; '.
1653
        get_string('email_body_recording_ready_is_ready', 'bigbluebuttonbn').'.</p>';
1654
    \mod_bigbluebuttonbn\locallib\notifier::notification_send($sender, $bigbluebuttonbn, $messagetext);
0 ignored issues
show
Documentation introduced by
$messagetext is of type string, but the function expects a object.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1655
}
1656
1657
/**
1658
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
1659
 *
1660
 * @return boolean
1661
 */
1662
function bigbluebuttonbn_is_bn_server() {
1663
    $parsedurl = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'));
1664
    if (!isset($parsedurl['host'])) {
1665
        return false;
1666
    }
1667
    $h = $parsedurl['host'];
1668
    $hends = explode('.', $h);
1669
    $hendslength = count($hends);
1670
    return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
1671
}
1672
1673
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) {
1674
    if ($bbbsession['administrator']) {
1675
        $courses = get_courses('all', 'c.fullname ASC', 'c.id,c.shortname,c.fullname');
1676
        // It includes the name of the site as a course (category 0), so remove the first one.
1677
        unset($courses['1']);
1678
    } else {
1679
        $courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname');
1680
    }
1681
    $coursesforselect = [];
1682
    foreach ($courses as $course) {
1683
        $coursesforselect[$course->id] = $course->fullname;
1684
    }
1685
    return $coursesforselect;
1686
}
1687
1688
function bigbluebutton_output_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1689
    if (isset($recordings) && !empty($recordings)) {
1690
        // There are recordings for this meeting.
1691
        $table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools);
1692
    }
1693
    if (!isset($table) || !isset($table->data)) {
1694
        // Render a table qith "No recordings".
1695
        return html_writer::div(get_string('view_message_norecordings', 'bigbluebuttonbn'), '',
1696
            array('id' => 'bigbluebuttonbn_html_table'));
1697
    }
1698
    // Render the table.
1699
    return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_html_table'));
1700
}
1701
1702
/**
1703
 * Helper function to convert an html string to plain text.
1704
 *
1705
 * @param string $html
1706
 * @param integer $len
1707
 *
1708
 * @return string
1709
 */
1710
function bigbluebuttonbn_html2text($html, $len = 0) {
1711
    $text = strip_tags($html);
1712
    $text = str_replace('&nbsp;', ' ', $text);
1713
    $textlen = strlen($text);
1714
    $text = substr($text, 0, $len);
1715
    if ($textlen > $len) {
1716
        $text .= '...';
1717
    }
1718
    return $text;
1719
}
1720
1721
/**
1722
 * Helper function to obtain the tags linked to a bigbluebuttonbn activity
1723
 *
1724
 * @param string $id
1725
 *
1726
 * @return string containing the tags separated by commas
1727
 */
1728
function bigbluebuttonbn_get_tags($id) {
1729
    $tagsarray = core_tag_tag::get_item_tags_array('core', 'course_modules', $id);
1730
    return implode(',', $tagsarray);
1731
}
1732
1733
/**
1734
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1735
 * in the getRecordings request
1736
 *
1737
 * @param string $courseid
1738
 * @param string $bigbluebuttonbnid
1739
 * @param bool   $subset
1740
 *
1741
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1742
 */
1743
function bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid = null, $subset = true) {
1744
    if (empty($courseid)) {
1745
        $courseid = 0;
1746
    }
1747
    if ($bigbluebuttonbnid === null) {
1748
        return "course = '{$courseid}'";
1749
    }
1750
    if ($subset) {
1751
        return "id = '{$bigbluebuttonbnid}'";
1752
    }
1753
    return "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'";
1754
}
1755
1756
/**
1757
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1758
 * in the getRecordings request considering only those that belong to deleted activities.
1759
 *
1760
 * @param string $courseid
1761
 * @param string $bigbluebuttonbnid
1762
 * @param bool   $subset
1763
 *
1764
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1765
 */
1766
function bigbluebuttonbn_get_recordings_sql_selectdeleted($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
1767
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_DELETE . "' AND meta like '%has_recordings%' AND meta like '%true%'";
1768
    if (empty($courseid)) {
1769
        $courseid = 0;
1770
    }
1771
    if ($bigbluebuttonbnid === null) {
1772
        return $sql . " AND courseid = {$courseid}";
1773
    }
1774
    if ($subset) {
1775
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
1776
    }
1777
    return $sql . " AND courseid = {$courseid} AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
1778
}
1779
1780
/**
1781
 * Helper function to get recordings  and imported recordings together.
1782
 *
1783
 * @param string $courseid
1784
 * @param string $bigbluebuttonbnid
1785
 * @param bool   $subset
1786
 * @param bool   $includedeleted
1787
 *
1788
 * @return associative array containing the recordings indexed by recordID, each recording is also a
1789
 * non sequential associative array itself that corresponds to the actual recording in BBB
1790
 */
1791
function bigbluebuttonbn_get_allrecordings($courseid, $bigbluebuttonbnid = null, $subset = true,
1792
        $includedeleted = false) {
1793
        $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $subset, $includedeleted);
1794
        $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset);
1795
        return ($recordings + $recordingsimported);
1796
}
1797
1798
/**
1799
 * Helper function to retrieve recordings from the BigBlueButton. The references are stored as events
1800
 * in bigbluebuttonbn_logs.
1801
 *
1802
 * @param string $courseid
1803
 * @param string $bigbluebuttonbnid
1804
 * @param bool   $subset
1805
 * @param bool   $includedeleted
1806
 *
1807
 * @return associative array containing the recordings indexed by recordID, each recording is also a
1808
 * non sequential associative array itself that corresponds to the actual recording in BBB
1809
 */
1810
function bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid = null, $subset = true,
1811
        $includedeleted = false) {
1812
    global $DB;
1813
    $select = bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid, $subset);
1814
    $bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid');
1815
    /* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in
1816
     * the getRecordings request. */
1817
    if ($includedeleted) {
1818
        $selectdeleted = bigbluebuttonbn_get_recordings_sql_selectdeleted($courseid, $bigbluebuttonbnid, $subset);
1819
        $bigbluebuttonbnsdel = $DB->get_records_select_menu('bigbluebuttonbn_logs', $selectdeleted, null,
1820
            'bigbluebuttonbnid', 'bigbluebuttonbnid, meetingid');
1821
        if (!empty($bigbluebuttonbnsdel)) {
1822
            // Merge bigbluebuttonbnis from deleted instances, only keys are relevant.
1823
            // Artimetic merge is used in order to keep the keys.
1824
            $bigbluebuttonbns += $bigbluebuttonbnsdel;
1825
        }
1826
    }
1827
    // Gather the meetingids from bigbluebuttonbn logs that include a create with record=true.
1828
    if (empty($bigbluebuttonbns)) {
1829
        return array();
1830
    }
1831
    // Prepare select for loading records based on existent bigbluebuttonbns.
1832
    $sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE ';
1833
    $sql .= '(bigbluebuttonbnid='.implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)).')';
1834
    // Include only Create events and exclude those with record not true.
1835
    $sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?';
1836
    // Execute select for loading records based on existent bigbluebuttonbns.
1837
    $records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%'));
1838
    // Get actual recordings.
1839
    return bigbluebuttonbn_get_recordings_array(array_keys($records));
1840
}
1841
1842
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) {
1843
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true);
1844
    foreach ($recordings as $key => $recording) {
1845
        if (isset($recordingsimported[$recording['recordID']])) {
1846
            unset($recordings[$key]);
1847
        }
1848
    }
1849
    return $recordings;
1850
}
1851
1852
/**
1853
 * Helper function to count the imported recordings for a recordingid.
1854
 *
1855
 * @param string $recordid
1856
 *
1857
 * @return integer
1858
 */
1859
function bigbluebuttonbn_get_count_recording_imported_instances($recordid) {
1860
    global $DB;
1861
    $sql = 'SELECT COUNT(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
1862
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%"));
1863
}
1864
1865
/**
1866
 * Helper function returns an array with all the instances of imported recordings for a recordingid.
1867
 *
1868
 * @param string $recordid
1869
 *
1870
 * @return array
1871
 */
1872
function bigbluebuttonbn_get_recording_imported_instances($recordid) {
1873
    global $DB;
1874
    $sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
1875
    $recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%',
1876
        "%{$recordid}%"));
1877
    return $recordingsimported;
1878
}
1879
1880
/**
1881
 * Helper function returns an array with the profiles (with features per profile) for the different types
1882
 * of bigbluebuttonbn instances.
1883
 *
1884
 * @return array
1885
 */
1886
function bigbluebuttonbn_get_instance_type_profiles() {
1887
    $instanceprofiles = array(
1888
            array('id' => BIGBLUEBUTTONBN_TYPE_ALL, 'name' => get_string('instance_type_default', 'bigbluebuttonbn'),
1889
                'features' => array('all')),
1890
            array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY, 'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'),
1891
                'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit', 'recording',
1892
                    'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups')),
1893
            array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY, 'name' => get_string('instance_type_recording_only',
1894
                'bigbluebuttonbn'), 'features' => array('showrecordings', 'importrecordings')),
1895
    );
1896
    return $instanceprofiles;
1897
}
1898
1899
/**
1900
 * Helper function returns an array with enabled features for an specific profile type.
1901
 *
1902
 * @param array $typeprofiles
1903
 * @param string $type
1904
 *
1905
 * @return array
1906
 */
1907
function bigbluebuttonbn_get_enabled_features($typeprofiles, $type = null) {
1908
    $enabledfeatures = array();
1909
    $features = $typeprofiles[0]['features'];
1910
    if (!is_null($type)) {
1911
        $features = $typeprofiles[$type]['features'];
1912
    }
1913
    $enabledfeatures['showroom'] = (in_array('all', $features) || in_array('showroom', $features));
1914
    // Evaluates if recordings are enabled for the Moodle site.
1915
    $enabledfeatures['showrecordings'] = (in_array('all', $features) || in_array('showrecordings', $features));
1916
    $enabledfeatures['importrecordings'] = (in_array('all', $features) || in_array('importrecordings', $features));
1917
    return $enabledfeatures;
1918
}
1919
1920
/**
1921
 * Helper function returns an array with the profiles (with features per profile) for the different types
1922
 * of bigbluebuttonbn instances.
1923
 *
1924
 * @param array $profiles
1925
 *
1926
 * @return array
1927
 */
1928
function bigbluebuttonbn_get_instance_profiles_array($profiles = null) {
1929
    if (is_null($profiles) || empty($profiles)) {
1930
        $profiles = bigbluebuttonbn_get_instance_type_profiles();
1931
    }
1932
    $profilesarray = array();
1933
    foreach ($profiles as $profile) {
1934
        $profilesarray += array("{$profile['id']}" => $profile['name']);
1935
    }
1936
    return $profilesarray;
1937
}
1938
1939
/**
1940
 * Helper function returns time in a formatted string.
1941
 *
1942
 * @param integer $time
1943
 *
1944
 * @return string
1945
 */
1946
function bigbluebuttonbn_format_activity_time($time) {
1947
    $activitytime = '';
1948
    if ($time) {
1949
        $activitytime = calendar_day_representation($time).' '.
1950
          get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn').' '.
1951
          calendar_time_representation($time);
1952
    }
1953
    return $activitytime;
1954
}
1955
1956
/**
1957
 * Helper function returns array with all the strings to be used in javascript.
1958
 *
1959
 * @return array
1960
 */
1961
function bigbluebuttonbn_get_strings_for_js() {
1962
    $locale = bigbluebuttonbn_get_locale();
1963
    $stringman = get_string_manager();
1964
    $strings = $stringman->load_component_strings('bigbluebuttonbn', $locale);
1965
    return $strings;
1966
}
1967
1968
/**
1969
 * Helper function returns the locale set by moodle.
1970
 *
1971
 * @return string
1972
 */
1973
function bigbluebuttonbn_get_locale() {
1974
    $lang = get_string('locale', 'core_langconfig');
1975
    return substr($lang, 0, strpos($lang, '.'));
1976
}
1977
1978
/**
1979
 * Helper function returns the locale code based on the locale set by moodle.
1980
 *
1981
 * @return string
1982
 */
1983
function bigbluebuttonbn_get_localcode() {
1984
    $locale = bigbluebuttonbn_get_locale();
1985
    return substr($locale, 0, strpos($locale, '_'));
1986
}
1987
1988
/**
1989
 * Helper function returns array with the instance settings used in views.
1990
 *
1991
 * @param string $id
1992
 * @param object $bigbluebuttonbnid
1993
 *
1994
 * @return array
1995
 */
1996
function bigbluebuttonbn_views_validator($id, $bigbluebuttonbnid) {
1997
    if ($id) {
1998
        return bigbluebuttonbn_views_instance_id($id);
1999
    }
2000
    if ($bigbluebuttonbnid) {
2001
        return bigbluebuttonbn_views_instance_bigbluebuttonbn($bigbluebuttonbnid);
2002
    }
2003
    return;
2004
}
2005
2006
/**
2007
 * Helper function returns array with the instance settings used in views based on id.
2008
 *
2009
 * @param string $id
2010
 *
2011
 * @return array
2012
 */
2013 View Code Duplication
function bigbluebuttonbn_views_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...
2014
    global $DB;
2015
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2016
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2017
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2018
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2019
}
2020
2021
/**
2022
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2023
 *
2024
 * @param object $bigbluebuttonbnid
2025
 *
2026
 * @return array
2027
 */
2028 View Code Duplication
function bigbluebuttonbn_views_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...
2029
    global $DB;
2030
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2031
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2032
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2033
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2034
}
2035
2036
/**
2037
 * Helper function renders general settings if the feature is enabled.
2038
 *
2039
 * @param object $renderer
2040
 *
2041
 * @return void
2042
 */
2043
function bigbluebutonbn_settings_general(&$renderer) {
2044
    // Configuration for BigBlueButton.
2045
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_general_shown()) {
2046
        $renderer->render_group_header('general');
2047
        $renderer->render_group_element('server_url',
2048
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL));
2049
        $renderer->render_group_element('shared_secret',
2050
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET));
2051
    }
2052
}
2053
2054
/**
2055
 * Helper function renders record settings if the feature is enabled.
2056
 *
2057
 * @param object $renderer
2058
 *
2059
 * @return void
2060
 */
2061
function bigbluebutonbn_settings_record(&$renderer) {
2062
    // Configuration for 'recording' feature.
2063 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::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...
2064
        $renderer->render_group_header('recording');
2065
        $renderer->render_group_element('recording_default',
2066
            $renderer->render_group_element_checkbox('recording_default', 1));
2067
        $renderer->render_group_element('recording_editable',
2068
            $renderer->render_group_element_checkbox('recording_editable', 1));
2069
        $renderer->render_group_element('recording_icons_enabled',
2070
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1));
2071
    }
2072
}
2073
2074
/**
2075
 * Helper function renders import recording settings if the feature is enabled.
2076
 *
2077
 * @param object $renderer
2078
 *
2079
 * @return void
2080
 */
2081 View Code Duplication
function bigbluebutonbn_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...
2082
    // Configuration for 'import recordings' feature.
2083
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_import_recordings_shown()) {
2084
        $renderer->render_group_header('importrecordings');
2085
        $renderer->render_group_element('importrecordings_enabled',
2086
            $renderer->render_group_element_checkbox('importrecordings_enabled', 0));
2087
        $renderer->render_group_element('importrecordings_from_deleted_enabled',
2088
            $renderer->render_group_element_checkbox('importrecordings_from_deleted_enabled', 0));
2089
    }
2090
}
2091
2092
/**
2093
 * Helper function renders show recording settings if the feature is enabled.
2094
 *
2095
 * @param object $renderer
2096
 *
2097
 * @return void
2098
 */
2099
function bigbluebutonbn_settings_showrecordings(&$renderer) {
2100
    // Configuration for 'show recordings' feature.
2101
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_show_recordings_shown()) {
2102
        $renderer->render_group_header('recordings');
2103
        $renderer->render_group_element('recordings_html_default',
2104
            $renderer->render_group_element_checkbox('recordings_html_default', 1));
2105
        $renderer->render_group_element('recordings_html_editable',
2106
            $renderer->render_group_element_checkbox('recordings_html_editable', 0));
2107
        $renderer->render_group_element('recordings_deleted_default',
2108
            $renderer->render_group_element_checkbox('recordings_deleted_default', 1));
2109
        $renderer->render_group_element('recordings_deleted_editable',
2110
            $renderer->render_group_element_checkbox('recordings_deleted_editable', 0));
2111
        $renderer->render_group_element('recordings_imported_default',
2112
            $renderer->render_group_element_checkbox('recordings_imported_default', 0));
2113
        $renderer->render_group_element('recordings_imported_editable',
2114
            $renderer->render_group_element_checkbox('recordings_imported_editable', 1));
2115
    }
2116
}
2117
2118
/**
2119
 * Helper function renders wait for moderator settings if the feature is enabled.
2120
 *
2121
 * @param object $renderer
2122
 *
2123
 * @return void
2124
 */
2125
function bigbluebutonbn_settings_waitmoderator(&$renderer) {
2126
    // Configuration for wait for moderator feature.
2127
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_wait_moderator_shown()) {
2128
        $renderer->render_group_header('waitformoderator');
2129
        $renderer->render_group_element('waitformoderator_default',
2130
            $renderer->render_group_element_checkbox('waitformoderator_default', 0));
2131
        $renderer->render_group_element('waitformoderator_editable',
2132
            $renderer->render_group_element_checkbox('waitformoderator_editable', 1));
2133
        $renderer->render_group_element('waitformoderator_ping_interval',
2134
            $renderer->render_group_element_text('waitformoderator_ping_interval', 10, PARAM_INT));
2135
        $renderer->render_group_element('waitformoderator_cache_ttl',
2136
            $renderer->render_group_element_text('waitformoderator_cache_ttl', 60, PARAM_INT));
2137
    }
2138
}
2139
2140
/**
2141
 * Helper function renders static voice bridge settings if the feature is enabled.
2142
 *
2143
 * @param object $renderer
2144
 *
2145
 * @return void
2146
 */
2147
function bigbluebutonbn_settings_voicebridge(&$renderer) {
2148
    // Configuration for "static voice bridge" feature.
2149
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_static_voice_bridge_shown()) {
2150
        $renderer->render_group_header('voicebridge');
2151
        $renderer->render_group_element('voicebridge_editable',
2152
            $renderer->render_group_element_checkbox('voicebridge_editable', 0));
2153
    }
2154
}
2155
2156
/**
2157
 * Helper function renders preuploaded presentation settings if the feature is enabled.
2158
 *
2159
 * @param object $renderer
2160
 *
2161
 * @return void
2162
 */
2163
function bigbluebutonbn_settings_preupload(&$renderer) {
2164
    // Configuration for "preupload presentation" feature.
2165
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_preupload_presentation_shown()) {
2166
        // This feature only works if curl is installed.
2167
        $preuploaddescripion = get_string('config_preuploadpresentation_description', 'bigbluebuttonbn');
2168
        if (!extension_loaded('curl')) {
2169
            $preuploaddescripion .= '<div class="form-defaultinfo">';
2170
            $preuploaddescripion .= get_string('config_warning_curl_not_installed', 'bigbluebuttonbn');
2171
            $preuploaddescripion .= '</div><br>';
2172
        }
2173
        $renderer->render_group_header('preuploadpresentation', null, $preuploaddescripion);
2174
        if (extension_loaded('curl')) {
2175
            $renderer->render_group_element('preuploadpresentation_enabled',
2176
                $renderer->render_group_element_checkbox('preuploadpresentation_enabled', 0));
2177
        }
2178
    }
2179
}
2180
2181
/**
2182
 * Helper function renders userlimit settings if the feature is enabled.
2183
 *
2184
 * @param object $renderer
2185
 *
2186
 * @return void
2187
 */
2188
function bigbluebutonbn_settings_userlimit(&$renderer) {
2189
    // Configuration for "user limit" feature.
2190
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_user_limit_shown()) {
2191
        $renderer->render_group_header('userlimit');
2192
        $renderer->render_group_element('userlimit_default',
2193
            $renderer->render_group_element_text('userlimit_default', 0, PARAM_INT));
2194
        $renderer->render_group_element('userlimit_editable',
2195
            $renderer->render_group_element_checkbox('userlimit_editable', 0));
2196
    }
2197
}
2198
2199
/**
2200
 * Helper function renders duration settings if the feature is enabled.
2201
 *
2202
 * @param object $renderer
2203
 *
2204
 * @return void
2205
 */
2206
function bigbluebutonbn_settings_duration(&$renderer) {
2207
    // Configuration for "scheduled duration" feature.
2208 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::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...
2209
        $renderer->render_group_header('scheduled');
2210
        $renderer->render_group_element('scheduled_duration_enabled',
2211
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1));
2212
        $renderer->render_group_element('scheduled_duration_compensation',
2213
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT));
2214
        $renderer->render_group_element('scheduled_pre_opening',
2215
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT));
2216
    }
2217
}
2218
2219
/**
2220
 * Helper function renders participant settings if the feature is enabled.
2221
 *
2222
 * @param object $renderer
2223
 *
2224
 * @return void
2225
 */
2226
function bigbluebutonbn_settings_participants(&$renderer) {
2227
    // Configuration for defining the default role/user that will be moderator on new activities.
2228
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_moderator_default_shown()) {
2229
        $renderer->render_group_header('participant');
2230
        // UI for 'participants' feature.
2231
        $roles = bigbluebuttonbn_get_roles();
2232
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2233
        $renderer->render_group_element('participant_moderator_default',
2234
            $renderer->render_group_element_configmultiselect('participant_moderator_default',
2235
                array_keys($owner), array_merge($owner, $roles))
2236
          );
2237
    }
2238
}
2239
2240
/**
2241
 * Helper function renders notification settings if the feature is enabled.
2242
 *
2243
 * @param object $renderer
2244
 *
2245
 * @return void
2246
 */
2247
function bigbluebutonbn_settings_notifications(&$renderer) {
2248
    // Configuration for "send notifications" feature.
2249
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_send_notifications_shown()) {
2250
        $renderer->render_group_header('sendnotifications');
2251
        $renderer->render_group_element('sendnotifications_enabled',
2252
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1));
2253
    }
2254
}
2255
2256
/**
2257
 * Helper function renders extended settings if any of the features there is enabled.
2258
 *
2259
 * @param object $renderer
2260
 *
2261
 * @return void
2262
 */
2263 View Code Duplication
function bigbluebutonbn_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...
2264
    // Configuration for extended BN capabilities.
2265
    if (!bigbluebuttonbn_is_bn_server()) {
2266
        return;
2267
    }
2268
    // Configuration for 'notify users when recording ready' feature.
2269
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_settings_extended_shown()) {
2270
        $renderer->render_group_header('extended_capabilities');
2271
        // UI for 'notify users when recording ready' feature.
2272
        $renderer->render_group_element('recordingready_enabled',
2273
            $renderer->render_group_element_checkbox('recordingready_enabled', 0));
2274
        // UI for 'register meeting events' feature.
2275
        $renderer->render_group_element('meetingevents_enabled',
2276
            $renderer->render_group_element_checkbox('meetingevents_enabled', 0));
2277
    }
2278
}
2279
2280
/**
2281
 * Helper function returns an encoded meetingid.
2282
 *
2283
 * @param string $seed
2284
 *
2285
 * @return string
2286
 */
2287
function bigbluebuttonbn_encode_meetingid($seed) {
2288
    global $CFG;
2289
    return sha1($CFG->wwwroot . $seed . \mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
2290
}
2291