Completed
Push — v2.3-stable ( b2b38f...061fb8 )
by Jesus
01:55
created

locallib.php ➔ bigbluebuttonbn_get_meeting_info()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 2
nop 2
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17
/**
18
 * Internal library of functions for module BigBlueButtonBN.
19
 *
20
 * @package   mod_bigbluebuttonbn
21
 * @copyright 2010 onwards, Blindside Networks Inc
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
24
 * @author    Fred Dixon  (ffdixon [at] blindsidenetworks [dt] com)
25
 */
26
27
use mod_bigbluebuttonbn\plugin;
28
29
defined('MOODLE_INTERNAL') || die;
30
31
global $CFG;
32
33
require_once(__DIR__.'/lib.php');
34
35
/** @var BIGBLUEBUTTONBN_UPDATE_CACHE boolean set to true indicates that cache has to be updated */
36
const BIGBLUEBUTTONBN_UPDATE_CACHE = true;
37
/** @var BIGBLUEBUTTONBN_TYPE_ALL integer set to 0 defines an instance type that inclueds room and recordings */
38
const BIGBLUEBUTTONBN_TYPE_ALL = 0;
39
/** @var BIGBLUEBUTTONBN_TYPE_ROOM_ONLY integer set to 1 defines an instance type that inclueds only room */
40
const BIGBLUEBUTTONBN_TYPE_ROOM_ONLY = 1;
41
/** @var BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY integer set to 2 defines an instance type that inclueds only recordings */
42
const BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY = 2;
43
/** @var BIGBLUEBUTTONBN_ROLE_VIEWER string defines the bigbluebutton viewer role */
44
const BIGBLUEBUTTONBN_ROLE_VIEWER = 'viewer';
45
/** @var BIGBLUEBUTTONBN_ROLE_MODERATOR string defines the bigbluebutton moderator role */
46
const BIGBLUEBUTTONBN_ROLE_MODERATOR = 'moderator';
47
/** @var BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED string defines the bigbluebuttonbn activity_viewed event */
48
const BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED = 'activity_viewed';
49
/** @var BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED string defines the bigbluebuttonbn activity_management_viewed event */
50
const BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED = 'activity_management_viewed';
51
/** @var BIGBLUEBUTTON_EVENT_LIVE_SESSION string defines the bigbluebuttonbn live_session event */
52
const BIGBLUEBUTTON_EVENT_LIVE_SESSION = 'live_session';
53
/** @var BIGBLUEBUTTON_EVENT_MEETING_CREATED string defines the bigbluebuttonbn meeting_created event */
54
const BIGBLUEBUTTON_EVENT_MEETING_CREATED = 'meeting_created';
55
/** @var BIGBLUEBUTTON_EVENT_MEETING_ENDED string defines the bigbluebuttonbn meeting_ended event */
56
const BIGBLUEBUTTON_EVENT_MEETING_ENDED = 'meeting_ended';
57
/** @var BIGBLUEBUTTON_EVENT_MEETING_JOINED string defines the bigbluebuttonbn meeting_joined event */
58
const BIGBLUEBUTTON_EVENT_MEETING_JOINED = 'meeting_joined';
59
/** @var BIGBLUEBUTTON_EVENT_MEETING_LEFT string defines the bigbluebuttonbn meeting_left event */
60
const BIGBLUEBUTTON_EVENT_MEETING_LEFT = 'meeting_left';
61
/** @var BIGBLUEBUTTON_EVENT_RECORDING_DELETED string defines the bigbluebuttonbn recording_deleted event */
62
const BIGBLUEBUTTON_EVENT_RECORDING_DELETED = 'recording_deleted';
63
/** @var BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED string defines the bigbluebuttonbn recording_imported event */
64
const BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED = 'recording_imported';
65
/** @var BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED string defines the bigbluebuttonbn recording_protected event */
66
const BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED = 'recording_protected';
67
/** @var BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED string defines the bigbluebuttonbn recording_published event */
68
const BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED = 'recording_published';
69
/** @var BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED string defines the bigbluebuttonbn recording_unprotected event */
70
const BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED = 'recording_unprotected';
71
/** @var BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED string defines the bigbluebuttonbn recording_unpublished event */
72
const BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED = 'recording_unpublished';
73
/** @var BIGBLUEBUTTON_EVENT_RECORDING_EDITED string defines the bigbluebuttonbn recording_edited event */
74
const BIGBLUEBUTTON_EVENT_RECORDING_EDITED = 'recording_edited';
75
/** @var BIGBLUEBUTTON_EVENT_RECORDING_VIEWED string defines the bigbluebuttonbn recording_viewed event */
76
const BIGBLUEBUTTON_EVENT_RECORDING_VIEWED = 'recording_viewed';
77
/** @var BIGBLUEBUTTON_EVENT_MEETING_START string defines the bigbluebuttonbn meeting_start event */
78
const BIGBLUEBUTTON_EVENT_MEETING_START = 'meeting_start';
79
/** @var BIGBLUEBUTTON_CLIENTTYPE_FLASH integer that defines the bigbluebuttonbn default web client based on Adobe FLASH */
80
const BIGBLUEBUTTON_CLIENTTYPE_FLASH = 0;
81
/** @var BIGBLUEBUTTON_CLIENTTYPE_HTML5 integer that defines the bigbluebuttonbn default web client based on HTML5 */
82
const BIGBLUEBUTTON_CLIENTTYPE_HTML5 = 1;
83
/** @var BIGBLUEBUTTON_ORIGIN_BASE integer set to 0 defines that the user acceded the session from activity page */
84
const BIGBLUEBUTTON_ORIGIN_BASE = 0;
85
/** @var BIGBLUEBUTTON_ORIGIN_TIMELINE integer set to 1 defines that the user acceded the session from Timeline */
86
const BIGBLUEBUTTON_ORIGIN_TIMELINE = 1;
87
/** @var BIGBLUEBUTTON_ORIGIN_INDEX integer set to 2 defines that the user acceded the session from Index */
88
const BIGBLUEBUTTON_ORIGIN_INDEX = 2;
89
90
/**
91
 * Builds and retunrs a url for joining a bigbluebutton meeting.
92
 *
93
 * @param string $meetingid
94
 * @param string $username
95
 * @param string $pw
96
 * @param string $logouturl
97
 * @param string $configtoken
98
 * @param string $userid
99
 * @param string $clienttype
100
 *
101
 * @return string
102
 */
103
function bigbluebuttonbn_get_join_url($meetingid, $username, $pw, $logouturl, $configtoken = null,
104
        $userid = null, $clienttype = BIGBLUEBUTTON_CLIENTTYPE_FLASH) {
105
    $data = ['meetingID' => $meetingid,
106
              'fullName' => $username,
107
              'password' => $pw,
108
              'logoutURL' => $logouturl,
109
            ];
110
    // Choose between Adobe Flash or HTML5 Client.
111
    if ( $clienttype == BIGBLUEBUTTON_CLIENTTYPE_HTML5 ) {
112
        $data['joinViaHtml5'] = 'true';
113
    }
114
    if (!is_null($configtoken)) {
115
        $data['configToken'] = $configtoken;
116
    }
117
    if (!is_null($userid)) {
118
        $data['userID'] = $userid;
119
    }
120
    return \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('join', $data);
121
}
122
123
/**
124
 * Creates a bigbluebutton meeting and returns the response in an array.
125
 *
126
 * @param array  $data
127
 * @param array  $metadata
128
 * @param string $pname
129
 * @param string $purl
130
 *
131
 * @return array
132
 */
133
function bigbluebuttonbn_get_create_meeting_array($data, $metadata = array(), $pname = null, $purl = null) {
134
    $createmeetingurl = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('create', $data, $metadata);
135
    $method = 'GET';
136
    $payload = null;
137
    if (!is_null($pname) && !is_null($purl)) {
138
        $method = 'POST';
139
        $payload = "<?xml version='1.0' encoding='UTF-8'?><modules><module name='presentation'><document url='".
140
            $purl."' /></module></modules>";
141
    }
142
    $xml = bigbluebuttonbn_wrap_xml_load_file($createmeetingurl, $method, $payload);
143
    if ($xml) {
144
        $response = array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
145
        if ($xml->meetingID) {
146
            $response += array('meetingID' => $xml->meetingID, 'attendeePW' => $xml->attendeePW,
147
                'moderatorPW' => $xml->moderatorPW, 'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded);
148
        }
149
        return $response;
150
    }
151
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
152
}
153
154
/**
155
 * Fetch meeting info and wrap response in array.
156
 *
157
 * @param string $meetingid
158
 *
159
 * @return array
160
 */
161
function bigbluebuttonbn_get_meeting_info_array($meetingid) {
162
    $xml = bigbluebuttonbn_wrap_xml_load_file(
163
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
164
      );
165
    if ($xml && $xml->returncode == 'SUCCESS' && empty($xml->messageKey)) {
166
        // Meeting info was returned.
167
        return array('returncode' => $xml->returncode,
168
                     'meetingID' => $xml->meetingID,
169
                     'moderatorPW' => $xml->moderatorPW,
170
                     'attendeePW' => $xml->attendeePW,
171
                     'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded,
172
                     'running' => $xml->running,
173
                     'recording' => $xml->recording,
174
                     'startTime' => $xml->startTime,
175
                     'endTime' => $xml->endTime,
176
                     'participantCount' => $xml->participantCount,
177
                     'moderatorCount' => $xml->moderatorCount,
178
                     'attendees' => $xml->attendees,
179
                     'metadata' => $xml->metadata,
180
                   );
181
    }
182
    if ($xml) {
183
        // Either failure or success without meeting info.
184
        return (array)$xml;
185
    }
186
    // If the server is unreachable, then prompts the user of the necessary action.
187
    return array('returncode' => 'FAILED', 'message' => 'unreachable', 'messageKey' => 'Server is unreachable');
188
}
189
190
/**
191
 * Helper function to retrieve recordings from a BigBlueButton server.
192
 *
193
 * @param string|array $meetingids   list of meetingIDs "mid1,mid2,mid3" or array("mid1","mid2","mid3")
194
 * @param string|array $recordingids list of $recordingids "rid1,rid2,rid3" or array("rid1","rid2","rid3") for filtering
195
 *
196
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
197
 */
198
function bigbluebuttonbn_get_recordings_array($meetingids, $recordingids = []) {
199
    $meetingidsarray = $meetingids;
200
    if (!is_array($meetingids)) {
201
        $meetingidsarray = explode(',', $meetingids);
202
    }
203
    // If $meetingidsarray is empty there is no need to go further.
204
    if (empty($meetingidsarray)) {
205
        return array();
206
    }
207
    $recordings = bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray);
0 ignored issues
show
Bug introduced by
It seems like $meetingidsarray defined by $meetingids on line 199 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...
208
    // Sort recordings.
209
    uasort($recordings, 'bigbluebuttonbn_recording_build_sorter');
210
    // Filter recordings based on recordingIDs.
211
    $recordingidsarray = $recordingids;
212
    if (!is_array($recordingids)) {
213
        $recordingidsarray = explode(',', $recordingids);
214
    }
215
    if (empty($recordingidsarray)) {
216
        // No recording ids, no need to filter.
217
        return $recordings;
218
    }
219
    return bigbluebuttonbn_get_recordings_array_filter($recordingidsarray, $recordings);
0 ignored issues
show
Bug introduced by
It seems like $recordingidsarray defined by $recordingids on line 211 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...
220
}
221
222
/**
223
 * Helper function to fetch recordings from a BigBlueButton server.
224
 *
225
 * @param array $meetingidsarray   array with meeting ids in the form array("mid1","mid2","mid3")
226
 *
227
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
228
 */
229
function bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray) {
230
    $recordings = array();
231
    // Execute a paginated getRecordings request.
232
    $pagecount = 25;
233
    $pages = floor(count($meetingidsarray) / $pagecount) + 1;
234
    if (count($meetingidsarray) > 0 && count($meetingidsarray) % $pagecount == 0) {
235
        $pages--;
236
    }
237
    for ($page = 1; $page <= $pages; ++$page) {
238
        $mids = array_slice($meetingidsarray, ($page - 1) * $pagecount, $pagecount);
239
        $recordings += bigbluebuttonbn_get_recordings_array_fetch_page($mids);
240
    }
241
    return $recordings;
242
}
243
244
/**
245
 * Helper function to fetch one page of upto 25 recordings from a BigBlueButton server.
246
 *
247
 * @param array  $mids
248
 *
249
 * @return array
250
 */
251
function bigbluebuttonbn_get_recordings_array_fetch_page($mids) {
252
    $recordings = array();
253
    // Do getRecordings is executed using a method GET (supported by all versions of BBB).
254
    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings', ['meetingID' => implode(',', $mids)]);
255
    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
256
    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
257
        // If there were meetings already created.
258
        foreach ($xml->recordings->recording as $recordingxml) {
259
            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
260
            $recordings[$recording['recordID']] = $recording;
261
262
            // Check if there is childs.
263
            if (isset($recordingxml->breakoutRooms->breakoutRoom)) {
264
                foreach ($recordingxml->breakoutRooms->breakoutRoom as $breakoutroom) {
265
                    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings',
266
                        ['recordID' => implode(',', (array) $breakoutroom)]);
267
                    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
268
                    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
269
                        // If there were meetings already created.
270
                        foreach ($xml->recordings->recording as $recordingxml) {
271
                            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
272
                            $recordings[$recording['recordID']] = $recording;
273
                        }
274
                    }
275
                }
276
            }
277
        }
278
    }
279
    return $recordings;
280
}
281
282
/**
283
 * Helper function to remove a set of recordings from an array.
284
 *
285
 * @param array  $rids
286
 * @param array  $recordings
287
 *
288
 * @return array
289
 */
290
function bigbluebuttonbn_get_recordings_array_filter($rids, &$recordings) {
291
    foreach ($recordings as $key => $recording) {
292
        if (!in_array($recording['recordID'], $rids)) {
293
            unset($recordings[$key]);
294
        }
295
    }
296
    return $recordings;
297
}
298
299
/**
300
 * Helper function to retrieve imported recordings from the Moodle database.
301
 * The references are stored as events in bigbluebuttonbn_logs.
302
 *
303
 * @param string $courseid
304
 * @param string $bigbluebuttonbnid
305
 * @param bool   $subset
306
 *
307
 * @return associative array with imported recordings indexed by recordID, each recording
308
 * is a non sequential associative array that corresponds to the actual recording in BBB
309
 */
310
function bigbluebuttonbn_get_recordings_imported_array($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
311
    global $DB;
312
    $select = bigbluebuttonbn_get_recordings_imported_sql_select($courseid, $bigbluebuttonbnid, $subset);
313
    $recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select);
314
    $recordsimportedarray = array();
315
    foreach ($recordsimported as $recordimported) {
316
        $meta = json_decode($recordimported->meta, true);
317
        $recording = $meta['recording'];
318
        // Override imported flag with actual ID.
319
        $recording['imported'] = $recordimported->id;
320
        if (isset($recordimported->protected)) {
321
            $recording['protected'] = (string) $recordimported->protected;
322
        }
323
        $recordsimportedarray[$recording['recordID']] = $recording;
324
    }
325
    return $recordsimportedarray;
326
}
327
328
/**
329
 * Helper function to retrive the default config.xml file.
330
 *
331
 * @return string
332
 */
333
function bigbluebuttonbn_get_default_config_xml() {
334
    $xml = bigbluebuttonbn_wrap_xml_load_file(
335
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getDefaultConfigXML')
336
      );
337
    return $xml;
338
}
339
340
/**
341
 * Helper function to convert an xml recording object to an array in the format used by the plugin.
342
 *
343
 * @param object $recording
344
 *
345
 * @return array
346
 */
347
function bigbluebuttonbn_get_recording_array_value($recording) {
348
    // Add formats.
349
    $playbackarray = array();
350
    foreach ($recording->playback->format as $format) {
351
        $playbackarray[(string) $format->type] = array('type' => (string) $format->type,
352
            'url' => trim((string) $format->url), 'length' => (string) $format->length);
353
        // Add preview per format when existing.
354
        if ($format->preview) {
355
            $playbackarray[(string) $format->type]['preview'] = bigbluebuttonbn_get_recording_preview_images($format->preview);
356
        }
357
    }
358
    // Add the metadata to the recordings array.
359
    $metadataarray = bigbluebuttonbn_get_recording_array_meta(get_object_vars($recording->metadata));
360
    $recordingarray = array('recordID' => (string) $recording->recordID,
361
        'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
362
        'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
363
        'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray);
364
    if (isset($recording->protected)) {
365
        $recordingarray['protected'] = (string) $recording->protected;
366
    }
367
    return $recordingarray + $metadataarray;
368
}
369
370
/**
371
 * Helper function to convert an xml recording preview images to an array in the format used by the plugin.
372
 *
373
 * @param object $preview
374
 *
375
 * @return array
376
 */
377
function bigbluebuttonbn_get_recording_preview_images($preview) {
378
    $imagesarray = array();
379
    foreach ($preview->images->image as $image) {
380
        $imagearray = array('url' => trim((string) $image));
381
        foreach ($image->attributes() as $attkey => $attvalue) {
382
            $imagearray[$attkey] = (string) $attvalue;
383
        }
384
        array_push($imagesarray, $imagearray);
385
    }
386
    return $imagesarray;
387
}
388
389
/**
390
 * Helper function to convert an xml recording metadata object to an array in the format used by the plugin.
391
 *
392
 * @param array $metadata
393
 *
394
 * @return array
395
 */
396
function bigbluebuttonbn_get_recording_array_meta($metadata) {
397
    $metadataarray = array();
398
    foreach ($metadata as $key => $value) {
399
        if (is_object($value)) {
400
            $value = '';
401
        }
402
        $metadataarray['meta_'.$key] = $value;
403
    }
404
    return $metadataarray;
405
}
406
407
/**
408
 * Helper function to sort an array of recordings. It compares the startTime in two recording objecs.
409
 *
410
 * @param object $a
411
 * @param object $b
412
 *
413
 * @return array
414
 */
415
function bigbluebuttonbn_recording_build_sorter($a, $b) {
416
    global $CFG;
417
    $resultless = !empty($CFG->bigbluebuttonbn_recordings_sortorder) ? -1 : 1;
418
    $resultmore = !empty($CFG->bigbluebuttonbn_recordings_sortorder) ? 1 : -1;
419
    if ($a['startTime'] < $b['startTime']) {
420
        return $resultless;
421
    }
422
    if ($a['startTime'] == $b['startTime']) {
423
        return 0;
424
    }
425
    return $resultmore;
426
}
427
428
/**
429
 * Perform deleteRecordings on BBB.
430
 *
431
 * @param string $recordids
432
 *
433
 * @return boolean
434
 */
435 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...
436
    $ids = explode(',', $recordids);
437
    foreach ($ids as $id) {
438
        $xml = bigbluebuttonbn_wrap_xml_load_file(
439
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('deleteRecordings', ['recordID' => $id])
440
          );
441
        if ($xml && $xml->returncode != 'SUCCESS') {
442
            return false;
443
        }
444
    }
445
    return true;
446
}
447
448
/**
449
 * Perform publishRecordings on BBB.
450
 *
451
 * @param string $recordids
452
 * @param string $publish
453
 */
454 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...
455
    $ids = explode(',', $recordids);
456
    foreach ($ids as $id) {
457
        $xml = bigbluebuttonbn_wrap_xml_load_file(
458
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish])
459
          );
460
        if ($xml && $xml->returncode != 'SUCCESS') {
461
            return false;
462
        }
463
    }
464
    return true;
465
}
466
467
/**
468
 * Perform updateRecordings on BBB.
469
 *
470
 * @param string $recordids
471
 * @param array $params ['key'=>param_key, 'value']
472
 */
473 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...
474
    $ids = explode(',', $recordids);
475
    foreach ($ids as $id) {
476
        $xml = bigbluebuttonbn_wrap_xml_load_file(
477
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('updateRecordings', ['recordID' => $id] + (array) $params)
478
          );
479
        if ($xml && $xml->returncode != 'SUCCESS') {
480
            return false;
481
        }
482
    }
483
    return true;
484
}
485
486
/**
487
 * Perform end on BBB.
488
 *
489
 * @param string $meetingid
490
 * @param string $modpw
491
 */
492
function bigbluebuttonbn_end_meeting($meetingid, $modpw) {
493
    $xml = bigbluebuttonbn_wrap_xml_load_file(
494
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('end', ['meetingID' => $meetingid, 'password' => $modpw])
495
      );
496
    if ($xml) {
497
        // If the xml packet returned failure it displays the message to the user.
498
        return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
499
    }
500
    // If the server is unreachable, then prompts the user of the necessary action.
501
    return null;
502
}
503
504
/**
505
 * Perform api request on BBB.
506
 *
507
 * @return string
508
 */
509
function bigbluebuttonbn_get_server_version() {
510
    $xml = bigbluebuttonbn_wrap_xml_load_file(
511
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url()
512
      );
513
    if ($xml && $xml->returncode == 'SUCCESS') {
514
        return $xml->version;
515
    }
516
    return null;
517
}
518
519
/**
520
 * Perform api request on BBB and wraps the response in an XML object
521
 *
522
 * @param string $url
523
 * @param string $method
524
 * @param string $data
525
 * @param string $contenttype
526
 *
527
 * @return object
528
 */
529
function bigbluebuttonbn_wrap_xml_load_file($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
530
    if (extension_loaded('curl')) {
531
        $response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype);
532
        if (!$response) {
533
            debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER);
534
            return null;
535
        }
536
        $previous = libxml_use_internal_errors(true);
537
        try {
538
            $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
539
            return $xml;
540
        } catch (Exception $e) {
541
            libxml_use_internal_errors($previous);
542
            $error = 'Caught exception: '.$e->getMessage();
543
            debugging($error, DEBUG_DEVELOPER);
544
            return null;
545
        }
546
    }
547
    // Alternative request non CURL based.
548
    $previous = libxml_use_internal_errors(true);
549
    try {
550
        $response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
551
        return $response;
552
    } catch (Exception $e) {
553
        $error = 'Caught exception: '.$e->getMessage();
554
        debugging($error, DEBUG_DEVELOPER);
555
        libxml_use_internal_errors($previous);
556
        return null;
557
    }
558
}
559
560
/**
561
 * Perform api request on BBB using CURL and wraps the response in an XML object
562
 *
563
 * @param string $url
564
 * @param string $method
565
 * @param string $data
566
 * @param string $contenttype
567
 *
568
 * @return object
569
 */
570
function bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
571
    global $CFG;
572
    require_once($CFG->libdir . '/filelib.php');
573
    $c = new curl();
574
    $c->setopt(array('SSL_VERIFYPEER' => true));
575
    if ($method == 'POST') {
576
        if (is_null($data) || is_array($data)) {
577
            return $c->post($url);
578
        }
579
        $options = array();
580
        $options['CURLOPT_HTTPHEADER'] = array(
581
                 'Content-Type: '.$contenttype,
582
                 'Content-Length: '.strlen($data),
583
                 'Content-Language: en-US',
584
               );
585
586
        return $c->post($url, $data, $options);
587
    }
588
    if ($method == 'HEAD') {
589
        $c->head($url, array('followlocation' => true, 'timeout' => 1));
590
        return $c->get_info();
591
    }
592
    return $c->get($url);
593
}
594
595
/**
596
 * End the session associated with this instance (if it's running).
597
 *
598
 * @param object $bigbluebuttonbn
599
 *
600
 * @return void
601
 */
602
function bigbluebuttonbn_end_meeting_if_running($bigbluebuttonbn) {
603
    $meetingid = $bigbluebuttonbn->meetingid.'-'.$bigbluebuttonbn->course.'-'.$bigbluebuttonbn->id;
604
    if (bigbluebuttonbn_is_meeting_running($meetingid)) {
605
        bigbluebuttonbn_end_meeting($meetingid, $bigbluebuttonbn->moderatorpass);
606
    }
607
}
608
609
/**
610
 * Returns user roles in a context.
611
 *
612
 * @param object $context
613
 * @param integer $userid
614
 *
615
 * @return array $userroles
616
 */
617
function bigbluebuttonbn_get_user_roles($context, $userid) {
618
    global $DB;
619
    $userroles = get_user_roles($context, $userid);
620
    if ($userroles) {
621
        $where = '';
622
        foreach ($userroles as $userrole) {
623
            $where .= (empty($where) ? ' WHERE' : ' OR').' id=' . $userrole->roleid;
624
        }
625
        $userroles = $DB->get_records_sql('SELECT * FROM {role}'.$where);
626
    }
627
    return $userroles;
628
}
629
630
/**
631
 * Returns guest role wrapped in an array.
632
 *
633
 * @return array
634
 */
635
function bigbluebuttonbn_get_guest_role() {
636
    $guestrole = get_guest_role();
637
    return array($guestrole->id => $guestrole);
638
}
639
640
/**
641
 * Returns an array containing all the users in a context.
642
 *
643
 * @param context $context
644
 *
645
 * @return array $users
646
 */
647
function bigbluebuttonbn_get_users(context $context = null) {
648
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
649
    foreach ($users as $key => $value) {
650
        $users[$key] = fullname($value);
651
    }
652
    return $users;
653
}
654
655
/**
656
 * Returns an array containing all the users in a context wrapped for html select element.
657
 *
658
 * @param context_course $context
659
 * @param null $bbactivity
660
 * @return array $users
661
 * @throws coding_exception
662
 * @throws moodle_exception
663
 */
664
function bigbluebuttonbn_get_users_select(context_course $context, $bbactivity = null) {
665
    // CONTRIB-7972, check the group of current user and course group mode.
666
    $groups = null;
0 ignored issues
show
Unused Code introduced by
$groups is not used, you could remove the assignment.

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

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

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

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

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

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

Consider the following code example.

<?php

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

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

print $a . " - " . $c;

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

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
672
        $groupmode = groups_get_activity_groupmode($cm);
673
674
    }
675
    if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $context)) {
676
        global $USER;
677
        $groups = groups_get_all_groups($course->id, $USER->id);
678
        $users = [];
679
        foreach ($groups as $g) {
680
            $users += (array) get_enrolled_users($context, '', $g->id, 'u.*', null, 0, 0, true);
681
        }
682
    }
683
    return array_map(
684
            function($u) {
685
                return array('id' => $u->id, 'name' => fullname($u));
686
            },
687
            $users);
688
}
689
690
/**
691
 * Returns an array containing all the roles in a context.
692
 *
693
 * @param context $context
694
 * @param bool $onlyviewableroles
695
 *
696
 * @return array $roles
697
 */
698
function bigbluebuttonbn_get_roles(context $context = null, bool $onlyviewableroles = true) {
699
    global $CFG;
700
701
    if ($onlyviewableroles == true && $CFG->branch >= 35) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
702
        $roles = (array) get_viewable_roles($context);
703
        foreach ($roles as $key => $value) {
704
            $roles[$key] = $value;
705
        }
706
    } else {
707
        $roles = (array) role_get_names($context);
708
        foreach ($roles as $key => $value) {
709
            $roles[$key] = $value->localname;
710
        }
711
    }
712
713
    return $roles;
714
}
715
716
/**
717
 * Returns an array containing all the roles in a context wrapped for html select element.
718
 *
719
 * @param context $context
720
 * @param bool $onlyviewableroles
721
 *
722
 * @return array $users
723
 */
724
function bigbluebuttonbn_get_roles_select(context $context = null, bool $onlyviewableroles = true) {
725
    global $CFG;
726
727
    if ($onlyviewableroles == true && $CFG->branch >= 35) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
728
        $roles = (array) get_viewable_roles($context);
729
        foreach ($roles as $key => $value) {
730
            $roles[$key] = array('id' => $key, 'name' => $value);
731
        }
732
    } else {
733
        $roles = (array) role_get_names($context);
734
        foreach ($roles as $key => $value) {
735
            $roles[$key] = array('id' => $value->id, 'name' => $value->localname);
736
        }
737
    }
738
739
    return $roles;
740
}
741
742
/**
743
 * Returns role that corresponds to an id.
744
 *
745
 * @param string|integer $id
746
 *
747
 * @return object $role
748
 */
749
function bigbluebuttonbn_get_role($id) {
750
    $roles = (array) role_get_names();
751
    if (is_numeric($id) && isset($roles[$id])) {
752
        return (object)$roles[$id];
753
    }
754
    foreach ($roles as $role) {
755
        if ($role->shortname == $id) {
756
            return $role;
757
        }
758
    }
759
}
760
761
/**
762
 * Returns an array to populate a list of participants used in mod_form.js.
763
 *
764
 * @param context $context
765
 * @param null|object $bbactivity
766
 * @return array $data
767
 */
768
function bigbluebuttonbn_get_participant_data($context, $bbactivity = null) {
769
    $data = array(
770
        'all' => array(
771
            'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
772
            'children' => []
773
          )
774
      );
775
    $data['role'] = array(
776
        'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
777
        'children' => bigbluebuttonbn_get_roles_select($context, true)
778
      );
779
    $data['user'] = array(
780
        'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
781
        'children' => bigbluebuttonbn_get_users_select($context, $bbactivity),
0 ignored issues
show
Bug introduced by
It seems like $bbactivity defined by parameter $bbactivity on line 768 can also be of type object; however, bigbluebuttonbn_get_users_select() does only seem to accept null, maybe add an additional type check?

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

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

An additional type check may prevent trouble.

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

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

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

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

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

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

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

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

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

Loading history...
1078
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
1079
    }
1080
    $file = reset($files);
1081
    unset($files);
1082
    $pnoncevalue = null;
1083 View Code Duplication
    if (!is_null($id)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1084
        // Create the nonce component for granting a temporary public access.
1085
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn',
1086
            'presentation_cache');
1087
        $pnoncekey = sha1($id);
1088
        /* The item id was adapted for granting public access to the presentation once in order
1089
         * to allow BigBlueButton to gather the file. */
1090
        $pnoncevalue = bigbluebuttonbn_generate_nonce();
1091
        $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
1092
    }
1093
    $url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
1094
        $file->get_filearea(), $pnoncevalue, $file->get_filepath(), $file->get_filename());
1095
    return array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
1096
        'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file));
1097
}
1098
1099
/**
1100
 * Helper generates a nonce used for the preuploaded presentation callback url.
1101
 *
1102
 * @return string
1103
 */
1104
function bigbluebuttonbn_generate_nonce() {
1105
    $mt = microtime();
1106
    $rand = mt_rand();
1107
    return md5($mt.$rand);
1108
}
1109
1110
/**
1111
 * Helper generates a random password.
1112
 *
1113
 * @param integer $length
1114
 * @param string $unique
1115
 *
1116
 * @return string
1117
 */
1118
function bigbluebuttonbn_random_password($length = 8, $unique = "") {
1119
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1120
    do {
1121
        $password = substr(str_shuffle($chars), 0, $length);
1122
    } while ($unique == $password);
1123
    return $password;
1124
}
1125
1126
/**
1127
 * Helper register a bigbluebuttonbn event.
1128
 *
1129
 * @param string $type
1130
 * @param object $bigbluebuttonbn
1131
 * @param array $options [timecreated, userid, other]
1132
 *
1133
 * @return void
1134
 */
1135
function bigbluebuttonbn_event_log($type, $bigbluebuttonbn, $options = []) {
1136
    global $DB;
1137
    if (!in_array($type, \mod_bigbluebuttonbn\event\events::$events)) {
1138
        // No log will be created.
1139
        return;
1140
    }
1141
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
1142
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
1143
    $context = context_module::instance($cm->id);
1144
    $params = array('context' => $context, 'objectid' => $bigbluebuttonbn->id);
1145
    if (array_key_exists('timecreated', $options)) {
1146
        $params['timecreated'] = $options['timecreated'];
1147
    }
1148
    if (array_key_exists('userid', $options)) {
1149
        $params['userid'] = $options['userid'];
1150
    }
1151
    if (array_key_exists('other', $options)) {
1152
        $params['other'] = $options['other'];
1153
    }
1154
    $event = call_user_func_array('\mod_bigbluebuttonbn\event\\' . $type . '::create',
1155
        array($params));
1156
    $event->add_record_snapshot('course_modules', $cm);
1157
    $event->add_record_snapshot('course', $course);
1158
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
1159
    $event->trigger();
1160
}
1161
1162
/**
1163
 * Updates the meeting info cached object when a participant has joined.
1164
 *
1165
 * @param string $meetingid
1166
 * @param bool $ismoderator
1167
 *
1168
 * @return void
1169
 */
1170
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) {
1171
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1172
    $result = $cache->get($meetingid);
1173
    $meetinginfo = json_decode($result['meeting_info']);
1174
    $meetinginfo->participantCount += 1;
1175
    if ($ismoderator) {
1176
        $meetinginfo->moderatorCount += 1;
1177
    }
1178
    $cache->set($meetingid, array('creation_time' => $result['creation_time'],
1179
        'meeting_info' => json_encode($meetinginfo)));
1180
}
1181
1182
/**
1183
 * Gets a meeting info object cached or fetched from the live session.
1184
 *
1185
 * @param string $meetingid
1186
 * @param boolean $updatecache
1187
 *
1188
 * @return array
1189
 */
1190
function bigbluebuttonbn_get_meeting_info($meetingid, $updatecache = false) {
1191
    $cachettl = (int)\mod_bigbluebuttonbn\locallib\config::get('waitformoderator_cache_ttl');
1192
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1193
    $result = $cache->get($meetingid);
1194
    $now = time();
1195
    if (!$updatecache && !empty($result) && $now < ($result['creation_time'] + $cachettl)) {
1196
        // Use the value in the cache.
1197
        return (array) json_decode($result['meeting_info']);
1198
    }
1199
    // Ping again and refresh the cache.
1200
    $meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file(
1201
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
1202
      );
1203
    $cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo)));
1204
    return $meetinginfo;
1205
}
1206
1207
/**
1208
 * Perform isMeetingRunning on BBB.
1209
 *
1210
 * @param string $meetingid
1211
 * @param boolean $updatecache
1212
 *
1213
 * @return boolean
1214
 */
1215
function bigbluebuttonbn_is_meeting_running($meetingid, $updatecache = false) {
1216
    /* As a workaround to isMeetingRunning that always return SUCCESS but only returns true
1217
     * when at least one user is in the session, we use getMeetingInfo instead.
1218
     */
1219
    $meetinginfo = bigbluebuttonbn_get_meeting_info($meetingid, $updatecache);
1220
    return ($meetinginfo['returncode'] === 'SUCCESS');
1221
}
1222
1223
/**
1224
 * Publish an imported recording.
1225
 *
1226
 * @param string $id
1227
 * @param boolean $publish
1228
 *
1229
 * @return boolean
1230
 */
1231 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...
1232
    global $DB;
1233
    // Locate the record to be updated.
1234
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1235
    $meta = json_decode($record->meta, true);
1236
    // Prepare data for the update.
1237
    $meta['recording']['published'] = ($publish) ? 'true' : 'false';
1238
    $record->meta = json_encode($meta);
1239
    // Proceed with the update.
1240
    $DB->update_record('bigbluebuttonbn_logs', $record);
1241
    return true;
1242
}
1243
1244
/**
1245
 * Delete an imported recording.
1246
 *
1247
 * @param string $id
1248
 *
1249
 * @return boolean
1250
 */
1251
function bigbluebuttonbn_delete_recording_imported($id) {
1252
    global $DB;
1253
    // Execute delete.
1254
    $DB->delete_records('bigbluebuttonbn_logs', array('id' => $id));
1255
    return true;
1256
}
1257
1258
/**
1259
 * Update an imported recording.
1260
 *
1261
 * @param string $id
1262
 * @param array $params ['key'=>param_key, 'value']
1263
 *
1264
 * @return boolean
1265
 */
1266
function bigbluebuttonbn_update_recording_imported($id, $params) {
1267
    global $DB;
1268
    // Locate the record to be updated.
1269
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1270
    $meta = json_decode($record->meta, true);
1271
    // Prepare data for the update.
1272
    $meta['recording'] = $params + $meta['recording'];
1273
    $record->meta = json_encode($meta);
1274
    // Proceed with the update.
1275
    if (!$DB->update_record('bigbluebuttonbn_logs', $record)) {
1276
        return false;
1277
    }
1278
    return true;
1279
}
1280
1281
/**
1282
 * Protect/Unprotect an imported recording.
1283
 *
1284
 * @param string $id
1285
 * @param boolean $protect
1286
 *
1287
 * @return boolean
1288
 */
1289 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...
1290
    global $DB;
1291
    // Locate the record to be updated.
1292
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1293
    $meta = json_decode($record->meta, true);
1294
    // Prepare data for the update.
1295
    $meta['recording']['protected'] = ($protect) ? 'true' : 'false';
1296
    $record->meta = json_encode($meta);
1297
    // Proceed with the update.
1298
    $DB->update_record('bigbluebuttonbn_logs', $record);
1299
    return true;
1300
}
1301
1302
/**
1303
 * Sets a custom config.xml file for being used on create.
1304
 *
1305
 * @param string $meetingid
1306
 * @param string $configxml
1307
 *
1308
 * @return object
1309
 */
1310
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) {
1311
    $urldefaultconfig = \mod_bigbluebuttonbn\locallib\config::get('server_url').'api/setConfigXML?';
1312
    $configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml);
1313
    $xml = bigbluebuttonbn_wrap_xml_load_file($urldefaultconfig, 'POST',
1314
        $configxmlparams, 'application/x-www-form-urlencoded');
1315
    return $xml;
1316
}
1317
1318
/**
1319
 * Sets qs used with a custom config.xml file request.
1320
 *
1321
 * @param string $meetingid
1322
 * @param string $configxml
1323
 *
1324
 * @return string
1325
 */
1326
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) {
1327
    $params = 'configXML='.urlencode($configxml).'&meetingID='.urlencode($meetingid);
1328
    $configxmlparams = $params.'&checksum='.sha1('setConfigXML'.$params.\mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
1329
    return $configxmlparams;
1330
}
1331
1332
/**
1333
 * Sets a custom config.xml file for being used on create.
1334
 *
1335
 * @param string $meetingid
1336
 * @param string $configxml
1337
 *
1338
 * @return array
1339
 */
1340
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) {
1341
    $configxml = bigbluebuttonbn_set_config_xml($meetingid, $configxml);
1342
    $configxmlarray = (array) $configxml;
1343
    if ($configxmlarray['returncode'] != 'SUCCESS') {
1344
        debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER);
1345
        return '';
1346
    }
1347
    return $configxmlarray['configToken'];
1348
}
1349
1350
/**
1351
 * Helper function builds a row for the data used by the recording table.
1352
 *
1353
 * @param array $bbbsession
1354
 * @param array $recording
1355
 * @param array $tools
1356
 *
1357
 * @return array
1358
 */
1359
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['protect', 'publish', 'delete']) {
1360
    if (!bigbluebuttonbn_include_recording_table_row($bbbsession, $recording)) {
1361
        return;
1362
    }
1363
    $rowdata = new stdClass();
1364
    // Set recording_types.
1365
    $rowdata->playback = bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession);
1366
    // Set activity name.
1367
    $rowdata->recording = bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession);
1368
    // Set activity description.
1369
    $rowdata->description = bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession);
1370
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1371
        // Set recording_preview.
1372
        $rowdata->preview = bigbluebuttonbn_get_recording_data_row_preview($recording);
1373
    }
1374
    // Set date.
1375
    $rowdata->date = bigbluebuttonbn_get_recording_data_row_date($recording);
1376
    // Set formatted date.
1377
    $rowdata->date_formatted = bigbluebuttonbn_get_recording_data_row_date_formatted($rowdata->date);
1378
    // Set formatted duration.
1379
    $rowdata->duration_formatted = $rowdata->duration = bigbluebuttonbn_get_recording_data_row_duration($recording);
1380
    // Set actionbar, if user is allowed to manage recordings.
1381
    if ($bbbsession['managerecordings']) {
1382
        $rowdata->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools);
1383
    }
1384
    return $rowdata;
1385
}
1386
1387
/**
1388
 * Helper function evaluates if a row for the data used by the recording table is editable.
1389
 *
1390
 * @param array $bbbsession
1391
 *
1392
 * @return boolean
1393
 */
1394
function bigbluebuttonbn_get_recording_data_row_editable($bbbsession) {
1395
    return ($bbbsession['managerecordings'] && ((double)$bbbsession['serverversion'] >= 1.0 || $bbbsession['bnserver']));
1396
}
1397
1398
/**
1399
 * Helper function evaluates if recording preview should be included.
1400
 *
1401
 * @param array $bbbsession
1402
 *
1403
 * @return boolean
1404
 */
1405
function bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession) {
1406
    return ((double)$bbbsession['serverversion'] >= 1.0 && $bbbsession['bigbluebuttonbn']->recordings_preview == '1');
1407
}
1408
1409
/**
1410
 * Helper function converts recording date used in row for the data used by the recording table.
1411
 *
1412
 * @param array $recording
1413
 *
1414
 * @return integer
1415
 */
1416
function bigbluebuttonbn_get_recording_data_row_date($recording) {
1417
    if (!isset($recording['startTime'])) {
1418
        return 0;
1419
    }
1420
    return floatval($recording['startTime']);
1421
}
1422
1423
/**
1424
 * Helper function format recording date used in row for the data used by the recording table.
1425
 *
1426
 * @param integer $starttime
1427
 *
1428
 * @return string
1429
 */
1430
function bigbluebuttonbn_get_recording_data_row_date_formatted($starttime) {
1431
    global $USER;
1432
    $starttime = $starttime - ($starttime % 1000);
1433
    // Set formatted date.
1434
    $dateformat = get_string('strftimerecentfull', 'langconfig').' %Z';
1435
    return userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone));
1436
}
1437
1438
/**
1439
 * Helper function converts recording duration used in row for the data used by the recording table.
1440
 *
1441
 * @param array $recording
1442
 *
1443
 * @return integer
1444
 */
1445
function bigbluebuttonbn_get_recording_data_row_duration($recording) {
1446
    foreach (array_values($recording['playbacks']) as $playback) {
1447
        // Ignore restricted playbacks.
1448
        if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'true') {
1449
            continue;
1450
        }
1451
        // Take the lenght form the fist playback with an actual value.
1452
        if (!empty($playback['length'])) {
1453
            return intval($playback['length']);
1454
        }
1455
    }
1456
    return 0;
1457
}
1458
1459
/**
1460
 * Helper function builds recording actionbar used in row for the data used by the recording table.
1461
 *
1462
 * @param array $recording
1463
 * @param array $tools
1464
 *
1465
 * @return string
1466
 */
1467
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) {
1468
    $actionbar = '';
1469
    foreach ($tools as $tool) {
1470
        $buttonpayload = bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool);
1471
        if ($tool == 'protect') {
1472
            if (isset($recording['imported'])) {
1473
                $buttonpayload['disabled'] = 'disabled';
1474
            }
1475
            if (!isset($recording['protected'])) {
1476
                $buttonpayload['disabled'] = 'invisible';
1477
            }
1478
        }
1479
        $actionbar .= bigbluebuttonbn_actionbar_render_button($recording, $buttonpayload);
1480
    }
1481
    $head = html_writer::start_tag('div', array(
1482
        'id' => 'recording-actionbar-' . $recording['recordID'],
1483
        'data-recordingid' => $recording['recordID'],
1484
        'data-meetingid' => $recording['meetingID']));
1485
    $tail = html_writer::end_tag('div');
1486
    return $head . $actionbar . $tail;
1487
}
1488
1489
/**
1490
 * Helper function returns the corresponding payload for an actionbar button used in row
1491
 * for the data used by the recording table.
1492
 *
1493
 * @param array $recording
1494
 * @param array $tool
1495
 *
1496
 * @return array
1497
 */
1498
function bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool) {
1499
    if ($tool == 'protect') {
1500
        $protected = 'false';
1501
        if (isset($recording['protected'])) {
1502
            $protected = $recording['protected'];
1503
        }
1504
        return bigbluebuttonbn_get_recording_data_row_action_protect($protected);
1505
    }
1506
    if ($tool == 'publish') {
1507
        return bigbluebuttonbn_get_recording_data_row_action_publish($recording['published']);
1508
    }
1509
    return array('action' => $tool, 'tag' => $tool);
1510
}
1511
1512
/**
1513
 * Helper function returns the payload for protect action button used in row
1514
 * for the data used by the recording table.
1515
 *
1516
 * @param string $protected
1517
 *
1518
 * @return array
1519
 */
1520
function bigbluebuttonbn_get_recording_data_row_action_protect($protected) {
1521
    if ($protected == 'true') {
1522
        return array('action' => 'unprotect', 'tag' => 'lock');
1523
    }
1524
    return array('action' => 'protect', 'tag' => 'unlock');
1525
}
1526
1527
/**
1528
 * Helper function returns the payload for publish action button used in row
1529
 * for the data used by the recording table.
1530
 *
1531
 * @param string $published
1532
 *
1533
 * @return array
1534
 */
1535
function bigbluebuttonbn_get_recording_data_row_action_publish($published) {
1536
    if ($published == 'true') {
1537
        return array('action' => 'unpublish', 'tag' => 'hide');
1538
    }
1539
    return array('action' => 'publish', 'tag' => 'show');
1540
}
1541
1542
/**
1543
 * Helper function builds recording preview used in row for the data used by the recording table.
1544
 *
1545
 * @param array $recording
1546
 *
1547
 * @return string
1548
 */
1549
function bigbluebuttonbn_get_recording_data_row_preview($recording) {
1550
    $options = array('id' => 'preview-'.$recording['recordID']);
1551
    if ($recording['published'] === 'false') {
1552
        $options['hidden'] = 'hidden';
1553
    }
1554
    $recordingpreview = html_writer::start_tag('div', $options);
1555
    foreach ($recording['playbacks'] as $playback) {
1556
        if (isset($playback['preview'])) {
1557
            $recordingpreview .= bigbluebuttonbn_get_recording_data_row_preview_images($playback);
1558
            break;
1559
        }
1560
    }
1561
    $recordingpreview .= html_writer::end_tag('div');
1562
    return $recordingpreview;
1563
}
1564
1565
/**
1566
 * Helper function builds element with actual images used in recording preview row based on a selected playback.
1567
 *
1568
 * @param array $playback
1569
 *
1570
 * @return string
1571
 */
1572
function bigbluebuttonbn_get_recording_data_row_preview_images($playback) {
1573
    global $CFG;
1574
    $recordingpreview  = html_writer::start_tag('div', array('class' => 'container-fluid'));
1575
    $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1576
    foreach ($playback['preview'] as $image) {
1577
        if ($CFG->bigbluebuttonbn_recordings_validate_url && !bigbluebuttonbn_is_valid_resource(trim($image['url']))) {
1578
            return '';
1579
        }
1580
        $recordingpreview .= html_writer::start_tag('div', array('class' => ''));
1581
        $recordingpreview .= html_writer::empty_tag('img',
1582
            array('src' => trim($image['url']) . '?' . time(), 'class' => 'recording-thumbnail pull-left'));
1583
        $recordingpreview .= html_writer::end_tag('div');
1584
    }
1585
    $recordingpreview .= html_writer::end_tag('div');
1586
    $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1587
    $recordingpreview .= html_writer::tag('div', get_string('view_recording_preview_help', 'bigbluebuttonbn'),
1588
        array('class' => 'text-center text-muted small'));
1589
    $recordingpreview .= html_writer::end_tag('div');
1590
    $recordingpreview .= html_writer::end_tag('div');
1591
    return $recordingpreview;
1592
}
1593
1594
/**
1595
 * Helper function renders recording types to be used in row for the data used by the recording table.
1596
 *
1597
 * @param array $recording
1598
 * @param array $bbbsession
1599
 *
1600
 * @return string
1601
 */
1602
function bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession) {
1603
    $dataimported = 'false';
1604
    $title = '';
1605
    if (isset($recording['imported'])) {
1606
        $dataimported = 'true';
1607
        $title = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1608
    }
1609
    $visibility = '';
1610
    if ($recording['published'] === 'false') {
1611
        $visibility = 'hidden ';
1612
    }
1613
    $id = 'playbacks-'.$recording['recordID'];
1614
    $recordingtypes = html_writer::start_tag('div', array('id' => $id, 'data-imported' => $dataimported,
1615
          'data-meetingid' => $recording['meetingID'], 'data-recordingid' => $recording['recordID'],
1616
          'title' => $title, $visibility => $visibility));
1617
    foreach ($recording['playbacks'] as $playback) {
1618
        $recordingtypes .= bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback);
1619
    }
1620
    $recordingtypes .= html_writer::end_tag('div');
1621
    return $recordingtypes;
1622
}
1623
1624
/**
1625
 * Helper function renders the link used for recording type in row for the data used by the recording table.
1626
 *
1627
 * @param array $recording
1628
 * @param array $bbbsession
1629
 * @param array $playback
1630
 *
1631
 * @return string
1632
 */
1633
function bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback) {
1634
    global $CFG, $OUTPUT;
1635
    if (!bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback)) {
1636
        return '';
1637
    }
1638
    $text = bigbluebuttonbn_get_recording_type_text($playback['type']);
1639
    $href = $CFG->wwwroot . '/mod/bigbluebuttonbn/bbb_view.php?action=play&bn=' . $bbbsession['bigbluebuttonbn']->id .
1640
        '&mid=' . $recording['meetingID'] . '&rid=' . $recording['recordID'] . '&rtype=' . $playback['type'];
1641
    if (!isset($recording['imported']) || !isset($recording['protected']) || $recording['protected'] === 'false') {
1642
        $href .= '&href=' . urlencode(trim($playback['url']));
1643
    }
1644
    $linkattributes = array(
1645
        'id' => 'recording-play-' . $playback['type'] . '-' . $recording['recordID'],
1646
        'class' => 'btn btn-sm btn-default',
1647
        'onclick' => 'M.mod_bigbluebuttonbn.recordings.recordingPlay(this);',
1648
        'data-action' => 'play',
1649
        'data-target' => $playback['type'],
1650
        'data-href' => $href,
1651
      );
1652
    if ($CFG->bigbluebuttonbn_recordings_validate_url && !bigbluebuttonbn_is_bn_server()
1653
            && !bigbluebuttonbn_is_valid_resource(trim($playback['url']))) {
1654
        $linkattributes['class'] = 'btn btn-sm btn-warning';
1655
        $linkattributes['title'] = get_string('view_recording_format_errror_unreachable', 'bigbluebuttonbn');
1656
        unset($linkattributes['data-href']);
1657
    }
1658
    return $OUTPUT->action_link('#', $text, null, $linkattributes) . '&#32;';
1659
}
1660
1661
/**
1662
 * Helper function to handle yet unknown recording types
1663
 *
1664
 * @param string $playbacktype : for now presentation, video, statistics, capture, notes, podcast
1665
 *
1666
 * @return string the matching language string or a capitalised version of the provided string
1667
 */
1668
function bigbluebuttonbn_get_recording_type_text($playbacktype) {
1669
    // Check first if string exists, and if it does'nt just default to the capitalised version of the string.
1670
    $text = ucwords($playbacktype);
1671
    $typestringid = 'view_recording_format_' . $playbacktype;
1672
    if (get_string_manager()->string_exists($typestringid, 'bigbluebuttonbn')) {
1673
        $text = get_string($typestringid, 'bigbluebuttonbn');
1674
    }
1675
    return $text;
1676
}
1677
1678
/**
1679
 * Helper function validates a remote resource.
1680
 *
1681
 * @param string $url
1682
 *
1683
 * @return boolean
1684
 */
1685
function bigbluebuttonbn_is_valid_resource($url) {
1686
    $urlhost = parse_url($url, PHP_URL_HOST);
1687
    $serverurlhost = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'), PHP_URL_HOST);
1688
    // Skip validation when the recording URL host is the same as the configured BBB server.
1689
    if ($urlhost == $serverurlhost) {
1690
        return true;
1691
    }
1692
    // Skip validation when the recording URL was already validated.
1693
    $validatedurls = bigbluebuttonbn_cache_get('recordings_cache', 'validated_urls', array());
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a integer|null.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1694
    if (array_key_exists($urlhost, $validatedurls)) {
1695
        return $validatedurls[$urlhost];
1696
    }
1697
    // Validate the recording URL.
1698
    $validatedurls[$urlhost] = true;
1699
    $curlinfo = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, 'HEAD');
1700
    if (!isset($curlinfo['http_code']) || $curlinfo['http_code'] != 200) {
1701
        $error = "Resources hosted by " . $urlhost . " are unreachable. Server responded with code " . $curlinfo['http_code'];
1702
        debugging($error, DEBUG_DEVELOPER);
1703
        $validatedurls[$urlhost] = false;
1704
    }
1705
    bigbluebuttonbn_cache_set('recordings_cache', 'validated_urls', $validatedurls);
1706
    return $validatedurls[$urlhost];
1707
}
1708
1709
/**
1710
 * Helper function renders the name for meeting used in row for the data used by the recording table.
1711
 *
1712
 * @param array $recording
1713
 * @param array $bbbsession
1714
 *
1715
 * @return string
1716
 */
1717
function bigbluebuttonbn_get_recording_data_row_meeting($recording, $bbbsession) {
0 ignored issues
show
Unused Code introduced by
The parameter $bbbsession is not used and could be removed.

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

Loading history...
1718
    $payload = array();
1719
    $source = 'meetingName';
1720
    $metaname = trim($recording['meetingName']);
1721
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $source, $payload);
1722
}
1723
1724
/**
1725
 * Helper function renders the name for recording used in row for the data used by the recording table.
1726
 *
1727
 * @param array $recording
1728
 * @param array $bbbsession
1729
 *
1730
 * @return string
1731
 */
1732
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession) {
1733
    $payload = array();
1734 View Code Duplication
    if (bigbluebuttonbn_get_recording_data_row_editable($bbbsession)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1735
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1736
            'action' => 'edit', 'tag' => 'edit',
1737
            'target' => 'name');
1738
    }
1739
    $oldsource = 'meta_contextactivity';
1740
    if (isset($recording[$oldsource])) {
1741
        $metaname = trim($recording[$oldsource]);
1742
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $oldsource, $payload);
1743
    }
1744
    $newsource = 'meta_bbb-recording-name';
1745 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...
1746
        $metaname = trim($recording[$newsource]);
1747
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1748
    }
1749
    $metaname = trim($recording['meetingName']);
1750
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1751
}
1752
1753
/**
1754
 * Helper function renders the description for recording used in row for the data used by the recording table.
1755
 *
1756
 * @param array $recording
1757
 * @param array $bbbsession
1758
 *
1759
 * @return string
1760
 */
1761
function bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession) {
1762
    $payload = array();
1763 View Code Duplication
    if (bigbluebuttonbn_get_recording_data_row_editable($bbbsession)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1764
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1765
            'action' => 'edit', 'tag' => 'edit',
1766
            'target' => 'description');
1767
    }
1768
    $oldsource = 'meta_contextactivitydescription';
1769 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...
1770
        $metadescription = trim($recording[$oldsource]);
1771
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $oldsource, $payload);
1772
    }
1773
    $newsource = 'meta_bbb-recording-description';
1774 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...
1775
        $metadescription = trim($recording[$newsource]);
1776
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $newsource, $payload);
1777
    }
1778
    return bigbluebuttonbn_get_recording_data_row_text($recording, '', $newsource, $payload);
1779
}
1780
1781
/**
1782
 * Helper function renders text element for recording used in row for the data used by the recording table.
1783
 *
1784
 * @param array $recording
1785
 * @param string $text
1786
 * @param string $source
1787
 * @param array $data
1788
 *
1789
 * @return string
1790
 */
1791
function bigbluebuttonbn_get_recording_data_row_text($recording, $text, $source, $data) {
1792
    $htmltext = '<span>' . htmlentities($text) . '</span>';
1793
    if (empty($data)) {
1794
        return $htmltext;
1795
    }
1796
    $target = $data['action'] . '-' . $data['target'];
1797
    $id = 'recording-' . $target . '-' . $data['recordingid'];
1798
    $attributes = array('id' => $id, 'class' => 'quickeditlink col-md-20',
1799
        'data-recordingid' => $data['recordingid'], 'data-meetingid' => $data['meetingid'],
1800
        'data-target' => $data['target'], 'data-source' => $source);
1801
    $head = html_writer::start_tag('div', $attributes);
1802
    $tail = html_writer::end_tag('div');
1803
    $payload = array('action' => $data['action'], 'tag' => $data['tag'], 'target' => $data['target']);
1804
    $htmllink = bigbluebuttonbn_actionbar_render_button($recording, $payload);
1805
    return $head . $htmltext . $htmllink . $tail;
1806
}
1807
1808
/**
1809
 * Helper function render a button for the recording action bar
1810
 *
1811
 * @param array $recording
1812
 * @param array $data
1813
 *
1814
 * @return string
1815
 */
1816
function bigbluebuttonbn_actionbar_render_button($recording, $data) {
1817
    global $OUTPUT;
1818
    if (empty($data)) {
1819
        return '';
1820
    }
1821
    $target = $data['action'];
1822
    if (isset($data['target'])) {
1823
        $target .= '-' . $data['target'];
1824
    }
1825
    $id = 'recording-' . $target . '-' . $recording['recordID'];
1826
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recording' . ucfirst($data['action']) . '(this); return false;';
1827
    if ((boolean) \mod_bigbluebuttonbn\locallib\config::get('recording_icons_enabled')) {
1828
        // With icon for $manageaction.
1829
        $iconattributes = array('id' => $id, 'class' => 'iconsmall');
1830
        $linkattributes = array(
1831
            'id' => $id,
1832
            'onclick' => $onclick,
1833
            'data-action' => $data['action']
1834
          );
1835
        if (!isset($recording['imported'])) {
1836
            $linkattributes['data-links'] = bigbluebuttonbn_count_recording_imported_instances(
1837
              $recording['recordID']);
1838
        }
1839
        if (isset($data['disabled'])) {
1840
            $iconattributes['class'] .= ' fa-' . $data['disabled'];
1841
            $linkattributes['class'] = 'disabled';
1842
            unset($linkattributes['onclick']);
1843
        }
1844
        $icon = new pix_icon('i/'.$data['tag'],
1845
            get_string('view_recording_list_actionbar_' . $data['action'], 'bigbluebuttonbn'),
1846
            'moodle', $iconattributes);
1847
        return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false);
1848
    }
1849
    // With text for $manageaction.
1850
    $linkattributes = array('title' => get_string($data['tag']), 'class' => 'btn btn-xs btn-danger',
1851
        'onclick' => $onclick);
1852
    return $OUTPUT->action_link('#', get_string($data['action']), null, $linkattributes);
1853
}
1854
1855
/**
1856
 * Helper function builds the data used for headers by the recording table.
1857
 *
1858
 * @param array $bbbsession
1859
 *
1860
 * @return array
1861
 */
1862
function bigbluebuttonbn_get_recording_columns($bbbsession) {
1863
    $columns = array();
1864
    // Initialize table headers.
1865
    $columns[] = array('key' => 'playback', 'label' => get_string('view_recording_playback', 'bigbluebuttonbn'),
1866
        'width' => '125px', 'allowHTML' => true); // Note: here a strange bug noted whilst changing the columns, ref CONTRIB.
1867
    $columns[] = array('key' => 'recording', 'label' => get_string('view_recording_name', 'bigbluebuttonbn'),
1868
        'width' => '125px', 'allowHTML' => true);
1869
    $columns[] = array('key' => 'description', 'label' => get_string('view_recording_description', 'bigbluebuttonbn'),
1870
        'sortable' => true, 'width' => '250px', 'allowHTML' => true);
1871
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1872
        $columns[] = array('key' => 'preview', 'label' => get_string('view_recording_preview', 'bigbluebuttonbn'),
1873
            'width' => '250px', 'allowHTML' => true);
1874
    }
1875
    $columns[] = array('key' => 'date', 'label' => get_string('view_recording_date', 'bigbluebuttonbn'),
1876
        'sortable' => true, 'width' => '225px', 'allowHTML' => true);
1877
    $columns[] = array('key' => 'duration', 'label' => get_string('view_recording_duration', 'bigbluebuttonbn'),
1878
        'width' => '50px');
1879
    if ($bbbsession['managerecordings']) {
1880
        $columns[] = array('key' => 'actionbar', 'label' => get_string('view_recording_actionbar', 'bigbluebuttonbn'),
1881
            'width' => '120px', 'allowHTML' => true);
1882
    }
1883
    return $columns;
1884
}
1885
1886
/**
1887
 * Helper function builds the data used by the recording table.
1888
 *
1889
 * @param array $bbbsession
1890
 * @param array $recordings
1891
 * @param array $tools
1892
 *
1893
 * @return array
1894
 */
1895
function bigbluebuttonbn_get_recording_data($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1896
    $tabledata = array();
1897
    // Build table content.
1898
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
1899
        // There are recordings for this meeting.
1900
        foreach ($recordings as $recording) {
1901
            $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1902
            if (!empty($rowdata)) {
1903
                array_push($tabledata, $rowdata);
1904
            }
1905
        }
1906
    }
1907
    return $tabledata;
1908
}
1909
1910
/**
1911
 * Helper function builds the recording table.
1912
 *
1913
 * @param array $bbbsession
1914
 * @param array $recordings
1915
 * @param array $tools
1916
 *
1917
 * @return object
1918
 */
1919
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1920
    global $DB;
1921
    // Declare the table.
1922
    $table = new html_table();
1923
    $table->data = array();
1924
    // Initialize table headers.
1925
    $table->head[] = get_string('view_recording_playback', 'bigbluebuttonbn');
1926
    $table->head[] = get_string('view_recording_name', 'bigbluebuttonbn');
1927
    $table->head[] = get_string('view_recording_description', 'bigbluebuttonbn');
1928
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1929
        $table->head[] = get_string('view_recording_preview', 'bigbluebuttonbn');
1930
    }
1931
    $table->head[] = get_string('view_recording_date', 'bigbluebuttonbn');
1932
    $table->head[] = get_string('view_recording_duration', 'bigbluebuttonbn');
1933
    $table->align = array('left', 'left', 'left', 'left', 'left', 'center');
1934
    $table->size = array('', '', '', '', '', '');
1935
    if ($bbbsession['managerecordings']) {
1936
        $table->head[] = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1937
        $table->align[] = 'left';
1938
        $table->size[] = (count($tools) * 40) . 'px';
1939
    }
1940
    // Get the groups of the user.
1941
    $usergroups = groups_get_all_groups($bbbsession['course']->id, $bbbsession['userID']);
1942
1943
    // Build table content.
1944
    foreach ($recordings as $recording) {
1945
1946
        $meetingid = $recording['meetingID'];
0 ignored issues
show
Unused Code introduced by
$meetingid is not used, you could remove the assignment.

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

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

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

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

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

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

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

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

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

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

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

Consider the following code example.

<?php

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

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

print $a . " - " . $c;

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

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
1953
        $groupmode = groups_get_activity_groupmode($cm);
1954
        $displayrow = true;
1955
        if (($groupmode != VISIBLEGROUPS)
1956
                && !$bbbsession['administrator'] && !$bbbsession['moderator']) {
1957
            $groupid = explode('[', $recording['meetingID']);
1958
            if (isset($groupid[1])) {
1959
                // It is a group recording and the user is not moderator/administrator. Recording should not be included by default.
1960
                $displayrow = false;
1961
                $groupid = explode(']', $groupid[1]);
1962
                if (isset($groupid[0])) {
1963
                    foreach ($usergroups as $usergroup) {
1964
                        if ($usergroup->id == $groupid[0]) {
1965
                            // Include recording if the user is in the same group.
1966
                            $displayrow = true;
1967
                        }
1968
                    }
1969
                }
1970
            }
1971
        }
1972
        if ($displayrow) {
1973
            $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1974
            if (!empty($rowdata)) {
1975
                $row = bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata);
1976
                array_push($table->data, $row);
1977
            }
1978
        }
1979
    }
1980
    return $table;
1981
}
1982
1983
/**
1984
 * Helper function builds the recording table row and insert into table.
1985
 *
1986
 * @param array $bbbsession
1987
 * @param array $recording
1988
 * @param object $rowdata
1989
 *
1990
 * @return object
1991
 */
1992
function bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata) {
1993
    $row = new html_table_row();
1994
    $row->id = 'recording-tr-'.$recording['recordID'];
1995
    $row->attributes['data-imported'] = 'false';
1996
    $texthead = '';
1997
    $texttail = '';
1998
    if (isset($recording['imported'])) {
1999
        $row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn');
2000
        $row->attributes['data-imported'] = 'true';
2001
        $texthead = '<em>';
2002
        $texttail = '</em>';
2003
    }
2004
    $rowdata->date_formatted = str_replace(' ', '&nbsp;', $rowdata->date_formatted);
2005
    $row->cells = array();
2006
    $row->cells[] = $texthead . $rowdata->playback . $texttail;
2007
    $row->cells[] = $texthead . $rowdata->recording . $texttail;
2008
    $row->cells[] = $texthead . $rowdata->description . $texttail;
2009
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
2010
        $row->cells[] = $rowdata->preview;
2011
    }
2012
    $row->cells[] = $texthead . $rowdata->date_formatted . $texttail;
2013
    $row->cells[] = $rowdata->duration_formatted;
2014
    if ($bbbsession['managerecordings']) {
2015
        $row->cells[] = $rowdata->actionbar;
2016
    }
2017
    return $row;
2018
}
2019
2020
/**
2021
 * Helper function evaluates if recording row should be included in the table.
2022
 *
2023
 * @param array $bbbsession
2024
 * @param array $recording
2025
 *
2026
 * @return boolean
2027
 */
2028
function bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) {
2029
    // Exclude unpublished recordings, only if user has no rights to manage them.
2030
    if ($recording['published'] != 'true' && !$bbbsession['managerecordings']) {
2031
        return false;
2032
    }
2033
    // Imported recordings are always shown as long as they are published.
2034
    if (isset($recording['imported'])) {
2035
        return true;
2036
    }
2037
    // Administrators and moderators are always allowed.
2038
    if ($bbbsession['administrator'] || $bbbsession['moderator']) {
2039
        return true;
2040
    }
2041
    // When groups are enabled, exclude those to which the user doesn't have access to.
2042
    if (isset($bbbsession['group']) && $recording['meetingID'] != $bbbsession['meetingid']) {
2043
        return false;
2044
    }
2045
    return true;
2046
}
2047
2048
/**
2049
 * Helper function triggers a send notification when the recording is ready.
2050
 *
2051
 * @param object $bigbluebuttonbn
2052
 *
2053
 * @return void
2054
 */
2055
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) {
2056
    $sender = get_admin();
2057
    // Prepare message.
2058
    $messagetext = '<p>'.get_string('email_body_recording_ready_for', 'bigbluebuttonbn').
2059
        ' &quot;' . $bigbluebuttonbn->name . '&quot; '.
2060
        get_string('email_body_recording_ready_is_ready', 'bigbluebuttonbn').'.</p>';
2061
    $context = context_course::instance($bigbluebuttonbn->course);
0 ignored issues
show
Unused Code introduced by
$context is not used, you could remove the assignment.

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

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

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

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

Loading history...
2062
    \mod_bigbluebuttonbn\locallib\notifier::notification_send($sender, $bigbluebuttonbn, $messagetext);
2063
}
2064
2065
/**
2066
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
2067
 *
2068
 * @return boolean
2069
 */
2070
function bigbluebuttonbn_is_bn_server() {
2071
    if (\mod_bigbluebuttonbn\locallib\config::get('bn_server')) {
2072
        return true;
2073
    }
2074
    $parsedurl = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'));
2075
    if (!isset($parsedurl['host'])) {
2076
        return false;
2077
    }
2078
    $h = $parsedurl['host'];
2079
    $hends = explode('.', $h);
2080
    $hendslength = count($hends);
2081
    return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
2082
}
2083
2084
/**
2085
 * Helper function returns a list of courses a user has access to, wrapped in an array that can be used
2086
 * by a html select.
2087
 *
2088
 * @param array $bbbsession
2089
 *
2090
 * @return array
2091
 */
2092
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) {
2093
    if ($bbbsession['administrator']) {
2094
        $courses = get_courses('all', 'c.fullname ASC');
2095
        // It includes the name of the site as a course (category 0), so remove the first one.
2096
        unset($courses['1']);
2097
    } else {
2098
        $courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname');
2099
    }
2100
    $coursesforselect = [];
2101
    foreach ($courses as $course) {
2102
        $coursesforselect[$course->id] = $course->fullname . " (" . $course->shortname . ")";
2103
    }
2104
    return $coursesforselect;
2105
}
2106
2107
/**
2108
 * Helper function renders recording table.
2109
 *
2110
 * @param array $bbbsession
2111
 * @param array $recordings
2112
 * @param array $tools
2113
 *
2114
 * @return array
2115
 */
2116
function bigbluebuttonbn_output_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
2117
    if (isset($recordings) && !empty($recordings)) {
2118
        // There are recordings for this meeting.
2119
        $table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools);
2120
    }
2121
    if (!isset($table) || !isset($table->data)) {
2122
        // Render a table with "No recordings".
2123
        return html_writer::div(get_string('view_message_norecordings', 'bigbluebuttonbn'), '',
2124
            array('id' => 'bigbluebuttonbn_recordings_table'));
2125
    }
2126
    // Render the table.
2127
    return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_recordings_table'));
2128
}
2129
2130
/**
2131
 * Helper function to convert an html string to plain text.
2132
 *
2133
 * @param string $html
2134
 * @param integer $len
2135
 *
2136
 * @return string
2137
 */
2138
function bigbluebuttonbn_html2text($html, $len = 0) {
2139
    $text = strip_tags($html);
2140
    $text = str_replace('&nbsp;', ' ', $text);
2141
    $textlen = mb_strlen($text);
2142
    $text = mb_substr($text, 0, $len);
2143
    if ($textlen > $len) {
2144
        $text .= '...';
2145
    }
2146
    return $text;
2147
}
2148
2149
/**
2150
 * Helper function to obtain the tags linked to a bigbluebuttonbn activity
2151
 *
2152
 * @param string $id
2153
 *
2154
 * @return string containing the tags separated by commas
2155
 */
2156
function bigbluebuttonbn_get_tags($id) {
2157
    if (class_exists('core_tag_tag')) {
2158
        return implode(',', core_tag_tag::get_item_tags_array('core', 'course_modules', $id));
2159
    }
2160
    return implode(',', tag_get_tags('bigbluebuttonbn', $id));
2161
}
2162
2163
/**
2164
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2165
 * in the getRecordings request
2166
 *
2167
 * @param string $courseid
2168
 * @param string $bigbluebuttonbnid
2169
 * @param bool   $subset
2170
 *
2171
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2172
 */
2173
function bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid = null, $subset = true) {
2174
    if (empty($courseid)) {
2175
        $courseid = 0;
2176
    }
2177
    if (empty($bigbluebuttonbnid)) {
2178
        return "course = '{$courseid}'";
2179
    }
2180
    if ($subset) {
2181
        return "id = '{$bigbluebuttonbnid}'";
2182
    }
2183
    return "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'";
2184
}
2185
2186
/**
2187
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2188
 * in the getRecordings request considering only those that belong to deleted activities.
2189
 *
2190
 * @param string $courseid
2191
 * @param string $bigbluebuttonbnid
2192
 * @param bool   $subset
2193
 *
2194
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2195
 */
2196 View Code Duplication
function bigbluebuttonbn_get_recordings_deleted_sql_select($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2197
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_DELETE . "' AND meta like '%has_recordings%' AND meta like '%true%'";
2198
    if (empty($courseid)) {
2199
        $courseid = 0;
2200
    }
2201
    if (empty($bigbluebuttonbnid)) {
2202
        return $sql . " AND courseid = {$courseid}";
2203
    }
2204
    if ($subset) {
2205
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
2206
    }
2207
    return $sql . " AND courseid = {$courseid} AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
2208
}
2209
2210
/**
2211
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2212
 * in the getRecordings request considering only those that belong to imported recordings.
2213
 *
2214
 * @param string $courseid
2215
 * @param string $bigbluebuttonbnid
2216
 * @param bool   $subset
2217
 *
2218
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2219
 */
2220 View Code Duplication
function bigbluebuttonbn_get_recordings_imported_sql_select($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2221
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
2222
    if (empty($courseid)) {
2223
        $courseid = 0;
2224
    }
2225
    if (empty($bigbluebuttonbnid)) {
2226
        return $sql . " AND courseid = '{$courseid}'";
2227
    }
2228
    if ($subset) {
2229
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
2230
    }
2231
    return $sql . " AND courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
2232
}
2233
2234
/**
2235
 * Helper function to get recordings and imported recordings together.
2236
 *
2237
 * @param string $courseid
2238
 * @param string $bigbluebuttonbnid
2239
 * @param bool   $subset
2240
 * @param bool   $includedeleted
2241
 *
2242
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2243
 * non sequential associative array itself that corresponds to the actual recording in BBB
2244
 */
2245
function bigbluebuttonbn_get_allrecordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
2246
    $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $subset, $includedeleted);
2247
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset);
2248
    return ($recordings + $recordingsimported);
2249
}
2250
2251
/**
2252
 * Helper function to retrieve recordings from the BigBlueButton. The references are stored as events
2253
 * in bigbluebuttonbn_logs.
2254
 *
2255
 * @param string $courseid
2256
 * @param string $bigbluebuttonbnid
2257
 * @param bool   $subset
2258
 * @param bool   $includedeleted
2259
 *
2260
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2261
 * non sequential associative array itself that corresponds to the actual recording in BBB
2262
 */
2263
function bigbluebuttonbn_get_recordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
2264
    global $DB;
2265
    $select = bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid, $subset);
2266
    $bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid');
2267
    /* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in
2268
     * the getRecordings request. */
2269
    if ($includedeleted) {
2270
        $selectdeleted = bigbluebuttonbn_get_recordings_deleted_sql_select($courseid, $bigbluebuttonbnid, $subset);
2271
        $bigbluebuttonbnsdel = $DB->get_records_select_menu('bigbluebuttonbn_logs', $selectdeleted, null,
2272
            'bigbluebuttonbnid', 'bigbluebuttonbnid, meetingid');
2273
        if (!empty($bigbluebuttonbnsdel)) {
2274
            // Merge bigbluebuttonbnis from deleted instances, only keys are relevant.
2275
            // Artimetic merge is used in order to keep the keys.
2276
            $bigbluebuttonbns += $bigbluebuttonbnsdel;
2277
        }
2278
    }
2279
    // Gather the meetingids from bigbluebuttonbn logs that include a create with record=true.
2280
    if (empty($bigbluebuttonbns)) {
2281
        return array();
2282
    }
2283
    // Prepare select for loading records based on existent bigbluebuttonbns.
2284
    $sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE ';
2285
    $sql .= '(bigbluebuttonbnid='.implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)).')';
2286
    // Include only Create events and exclude those with record not true.
2287
    $sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?';
2288
    // Execute select for loading records based on existent bigbluebuttonbns.
2289
    $records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%'));
2290
    // Get actual recordings.
2291
    return bigbluebuttonbn_get_recordings_array(array_keys($records));
2292
}
2293
2294
/**
2295
 * Helper function iterates an array with recordings and unset those already imported.
2296
 *
2297
 * @param array $recordings
2298
 * @param integer $courseid
2299
 * @param integer $bigbluebuttonbnid
2300
 *
2301
 * @return array
2302
 */
2303
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) {
2304
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true);
2305
    foreach ($recordings as $key => $recording) {
2306
        if (isset($recordingsimported[$recording['recordID']])) {
2307
            unset($recordings[$key]);
2308
        }
2309
    }
2310
    return $recordings;
2311
}
2312
2313
/**
2314
 * Helper function to count the imported recordings for a recordingid.
2315
 *
2316
 * @param string $recordid
2317
 *
2318
 * @return integer
2319
 */
2320
function bigbluebuttonbn_count_recording_imported_instances($recordid) {
2321
    global $DB;
2322
    $sql = 'SELECT COUNT(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2323
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%"));
2324
}
2325
2326
/**
2327
 * Helper function returns an array with all the instances of imported recordings for a recordingid.
2328
 *
2329
 * @param string $recordid
2330
 *
2331
 * @return array
2332
 */
2333
function bigbluebuttonbn_get_recording_imported_instances($recordid) {
2334
    global $DB;
2335
    $sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2336
    $recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%',
2337
        "%{$recordid}%"));
2338
    return $recordingsimported;
2339
}
2340
2341
/**
2342
 * Helper function to get how much callback events are logged.
2343
 *
2344
 * @param string $recordid
2345
 *
2346
 * @return integer
2347
 */
2348
function bigbluebuttonbn_get_count_callback_event_log($recordid) {
2349
    global $DB;
2350
    $sql = 'SELECT count(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2351
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTON_LOG_EVENT_CALLBACK, '%recordid%', "%{$recordid}%"));
2352
}
2353
2354
/**
2355
 * Helper function returns an array with the profiles (with features per profile) for the different types
2356
 * of bigbluebuttonbn instances.
2357
 *
2358
 * @return array
2359
 */
2360
function bigbluebuttonbn_get_instance_type_profiles() {
2361
    $instanceprofiles = array(
2362
        BIGBLUEBUTTONBN_TYPE_ALL => array('id' => BIGBLUEBUTTONBN_TYPE_ALL,
2363
                  'name' => get_string('instance_type_default', 'bigbluebuttonbn'),
2364
                  'features' => array('all')),
2365
        BIGBLUEBUTTONBN_TYPE_ROOM_ONLY => array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY,
2366
                  'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'),
2367
                  'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit',
2368
                      'recording', 'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups',
2369
                      'modstandardelshdr', 'availabilityconditionsheader', 'tagshdr', 'competenciessection',
2370
                      'clienttype', 'availabilityconditionsheader')),
2371
        BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY => array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY,
2372
                  'name' => get_string('instance_type_recording_only', 'bigbluebuttonbn'),
2373
                  'features' => array('showrecordings', 'importrecordings', 'availabilityconditionsheader'))
2374
    );
2375
    return $instanceprofiles;
2376
}
2377
2378
2379
/**
2380
 * Helper function returns an array with enabled features for an specific profile type.
2381
 *
2382
 * @param array $typeprofiles
2383
 * @param string $type
2384
 *
2385
 * @return array
2386
 */
2387
function bigbluebuttonbn_get_enabled_features($typeprofiles, $type = null) {
2388
    $enabledfeatures = array();
2389
    $features = $typeprofiles[BIGBLUEBUTTONBN_TYPE_ALL]['features'];
2390
    if (!is_null($type) && key_exists($type, $typeprofiles)) {
2391
        $features = $typeprofiles[$type]['features'];
2392
    }
2393
    $enabledfeatures['showroom'] = (in_array('all', $features) || in_array('showroom', $features));
2394
    // Evaluates if recordings are enabled for the Moodle site.
2395
    $enabledfeatures['showrecordings'] = false;
2396
    if (\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
2397
        $enabledfeatures['showrecordings'] = (in_array('all', $features) || in_array('showrecordings', $features));
2398
    }
2399
    $enabledfeatures['importrecordings'] = false;
2400
    if (\mod_bigbluebuttonbn\locallib\config::importrecordings_enabled()) {
2401
        $enabledfeatures['importrecordings'] = (in_array('all', $features) || in_array('importrecordings', $features));
2402
    }
2403
    // Evaluates if clienttype is enabled for the Moodle site.
2404
    $enabledfeatures['clienttype'] = false;
2405
    if (\mod_bigbluebuttonbn\locallib\config::clienttype_enabled()) {
2406
        $enabledfeatures['clienttype'] = (in_array('all', $features) || in_array('clienttype', $features));
2407
    }
2408
    return $enabledfeatures;
2409
}
2410
2411
/**
2412
 * Helper function returns an array with the profiles (with features per profile) for the different types
2413
 * of bigbluebuttonbn instances that the user is allowed to create.
2414
 *
2415
 * @param boolean $room
2416
 * @param boolean $recording
2417
 *
2418
 * @return array
2419
 */
2420
function bigbluebuttonbn_get_instance_type_profiles_create_allowed($room, $recording) {
2421
    $profiles = bigbluebuttonbn_get_instance_type_profiles();
2422
    if (!$room) {
2423
        unset($profiles[BIGBLUEBUTTONBN_TYPE_ROOM_ONLY]);
2424
        unset($profiles[BIGBLUEBUTTONBN_TYPE_ALL]);
2425
    }
2426
    if (!$recording) {
2427
        unset($profiles[BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY]);
2428
        unset($profiles[BIGBLUEBUTTONBN_TYPE_ALL]);
2429
    }
2430
    return $profiles;
2431
}
2432
2433
/**
2434
 * Helper function returns an array with the profiles (with features per profile) for the different types
2435
 * of bigbluebuttonbn instances.
2436
 *
2437
 * @param array $profiles
2438
 *
2439
 * @return array
2440
 */
2441
function bigbluebuttonbn_get_instance_profiles_array($profiles = []) {
2442
    $profilesarray = array();
2443
    foreach ($profiles as $key => $profile) {
2444
        $profilesarray[$profile['id']] = $profile['name'];
2445
    }
2446
    return $profilesarray;
2447
}
2448
2449
/**
2450
 * Helper function returns time in a formatted string.
2451
 *
2452
 * @param integer $time
2453
 *
2454
 * @return string
2455
 */
2456
function bigbluebuttonbn_format_activity_time($time) {
2457
    global $CFG;
2458
    require_once($CFG->dirroot.'/calendar/lib.php');
2459
    $activitytime = '';
2460
    if ($time) {
2461
        $activitytime = calendar_day_representation($time).' '.
2462
          get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn').' '.
2463
          calendar_time_representation($time);
2464
    }
2465
    return $activitytime;
2466
}
2467
2468
/**
2469
 * Helper function returns array with all the strings to be used in javascript.
2470
 *
2471
 * @return array
2472
 */
2473
function bigbluebuttonbn_get_strings_for_js() {
2474
    $locale = bigbluebuttonbn_get_locale();
2475
    $stringman = get_string_manager();
2476
    $strings = $stringman->load_component_strings('bigbluebuttonbn', $locale);
2477
    return $strings;
2478
}
2479
2480
/**
2481
 * Helper function returns the locale set by moodle.
2482
 *
2483
 * @return string
2484
 */
2485
function bigbluebuttonbn_get_locale() {
2486
    $lang = get_string('locale', 'core_langconfig');
2487
    return substr($lang, 0, strpos($lang, '.'));
2488
}
2489
2490
/**
2491
 * Helper function returns the locale code based on the locale set by moodle.
2492
 *
2493
 * @return string
2494
 */
2495
function bigbluebuttonbn_get_localcode() {
2496
    $locale = bigbluebuttonbn_get_locale();
2497
    return substr($locale, 0, strpos($locale, '_'));
2498
}
2499
2500
/**
2501
 * Helper function returns array with the instance settings used in views.
2502
 *
2503
 * @param string $id
2504
 * @param object $bigbluebuttonbnid
2505
 *
2506
 * @return array
2507
 */
2508
function bigbluebuttonbn_view_validator($id, $bigbluebuttonbnid) {
2509
    $result = null;
2510
    if ($id) {
2511
        $result = bigbluebuttonbn_view_instance_id($id);
2512
    } else if ($bigbluebuttonbnid) {
2513
        $result = bigbluebuttonbn_view_instance_bigbluebuttonbn($bigbluebuttonbnid);
2514
    }
2515
    return $result;
2516
}
2517
2518
/**
2519
 * Helper function returns array with the instance settings used in views based on id.
2520
 *
2521
 * @param string $id
2522
 *
2523
 * @return array
2524
 */
2525 View Code Duplication
function bigbluebuttonbn_view_instance_id($id) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2526
    global $DB;
2527
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2528
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2529
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2530
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2531
}
2532
2533
/**
2534
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2535
 *
2536
 * @param object $bigbluebuttonbnid
2537
 *
2538
 * @return array
2539
 */
2540 View Code Duplication
function bigbluebuttonbn_view_instance_bigbluebuttonbn($bigbluebuttonbnid) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2541
    global $DB;
2542
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2543
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2544
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2545
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2546
}
2547
2548
/**
2549
 * Helper function renders general settings if the feature is enabled.
2550
 *
2551
 * @param object $renderer
2552
 *
2553
 * @return void
2554
 */
2555
function bigbluebuttonbn_settings_general(&$renderer) {
2556
    // Configuration for BigBlueButton.
2557
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_general_shown()) {
2558
        $renderer->render_group_header('general');
2559
        $renderer->render_group_element('server_url',
2560
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL));
2561
        $renderer->render_group_element('shared_secret',
2562
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET));
2563
    }
2564
}
2565
2566
/**
2567
 * Helper function renders record settings if the feature is enabled.
2568
 *
2569
 * @param object $renderer
2570
 *
2571
 * @return void
2572
 */
2573
function bigbluebuttonbn_settings_record(&$renderer) {
2574
    // Configuration for 'recording' feature.
2575
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_record_meeting_shown()) {
2576
        $renderer->render_group_header('recording');
2577
        $renderer->render_group_element('recording_default',
2578
            $renderer->render_group_element_checkbox('recording_default', 1));
2579
        $renderer->render_group_element('recording_editable',
2580
            $renderer->render_group_element_checkbox('recording_editable', 1));
2581
        $renderer->render_group_element('recording_icons_enabled',
2582
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1));
2583
2584
        // Add recording start to load and allow/hide stop/pause.
2585
        $renderer->render_group_element('recording_all_from_start_default',
2586
            $renderer->render_group_element_checkbox('recording_all_from_start_default', 0));
2587
        $renderer->render_group_element('recording_all_from_start_editable',
2588
            $renderer->render_group_element_checkbox('recording_all_from_start_editable', 0));
2589
        $renderer->render_group_element('recording_hide_button_default',
2590
            $renderer->render_group_element_checkbox('recording_hide_button_default', 0));
2591
        $renderer->render_group_element('recording_hide_button_editable',
2592
            $renderer->render_group_element_checkbox('recording_hide_button_editable', 0));
2593
    }
2594
}
2595
2596
/**
2597
 * Helper function renders import recording settings if the feature is enabled.
2598
 *
2599
 * @param object $renderer
2600
 *
2601
 * @return void
2602
 */
2603 View Code Duplication
function bigbluebuttonbn_settings_importrecordings(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2604
    // Configuration for 'import recordings' feature.
2605
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_import_recordings_shown()) {
2606
        $renderer->render_group_header('importrecordings');
2607
        $renderer->render_group_element('importrecordings_enabled',
2608
            $renderer->render_group_element_checkbox('importrecordings_enabled', 0));
2609
        $renderer->render_group_element('importrecordings_from_deleted_enabled',
2610
            $renderer->render_group_element_checkbox('importrecordings_from_deleted_enabled', 0));
2611
    }
2612
}
2613
2614
/**
2615
 * Helper function renders show recording settings if the feature is enabled.
2616
 *
2617
 * @param object $renderer
2618
 *
2619
 * @return void
2620
 */
2621
function bigbluebuttonbn_settings_showrecordings(&$renderer) {
2622
    // Configuration for 'show recordings' feature.
2623
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_show_recordings_shown()) {
2624
        $renderer->render_group_header('recordings');
2625
        $renderer->render_group_element('recordings_html_default',
2626
            $renderer->render_group_element_checkbox('recordings_html_default', 1));
2627
        $renderer->render_group_element('recordings_html_editable',
2628
            $renderer->render_group_element_checkbox('recordings_html_editable', 0));
2629
        $renderer->render_group_element('recordings_deleted_default',
2630
            $renderer->render_group_element_checkbox('recordings_deleted_default', 1));
2631
        $renderer->render_group_element('recordings_deleted_editable',
2632
            $renderer->render_group_element_checkbox('recordings_deleted_editable', 0));
2633
        $renderer->render_group_element('recordings_imported_default',
2634
            $renderer->render_group_element_checkbox('recordings_imported_default', 0));
2635
        $renderer->render_group_element('recordings_imported_editable',
2636
            $renderer->render_group_element_checkbox('recordings_imported_editable', 1));
2637
        $renderer->render_group_element('recordings_preview_default',
2638
            $renderer->render_group_element_checkbox('recordings_preview_default', 1));
2639
        $renderer->render_group_element('recordings_preview_editable',
2640
            $renderer->render_group_element_checkbox('recordings_preview_editable', 0));
2641
        $renderer->render_group_element('recordings_sortorder',
2642
            $renderer->render_group_element_checkbox('recordings_sortorder', 0));
2643
        $renderer->render_group_element('recordings_validate_url',
2644
            $renderer->render_group_element_checkbox('recordings_validate_url', 1));
2645
    }
2646
}
2647
2648
/**
2649
 * Helper function renders wait for moderator settings if the feature is enabled.
2650
 *
2651
 * @param object $renderer
2652
 *
2653
 * @return void
2654
 */
2655
function bigbluebuttonbn_settings_waitmoderator(&$renderer) {
2656
    // Configuration for wait for moderator feature.
2657
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_wait_moderator_shown()) {
2658
        $renderer->render_group_header('waitformoderator');
2659
        $renderer->render_group_element('waitformoderator_default',
2660
            $renderer->render_group_element_checkbox('waitformoderator_default', 0));
2661
        $renderer->render_group_element('waitformoderator_editable',
2662
            $renderer->render_group_element_checkbox('waitformoderator_editable', 1));
2663
        $renderer->render_group_element('waitformoderator_ping_interval',
2664
            $renderer->render_group_element_text('waitformoderator_ping_interval', 10, PARAM_INT));
2665
        $renderer->render_group_element('waitformoderator_cache_ttl',
2666
            $renderer->render_group_element_text('waitformoderator_cache_ttl', 60, PARAM_INT));
2667
    }
2668
}
2669
2670
/**
2671
 * Helper function renders static voice bridge settings if the feature is enabled.
2672
 *
2673
 * @param object $renderer
2674
 *
2675
 * @return void
2676
 */
2677
function bigbluebuttonbn_settings_voicebridge(&$renderer) {
2678
    // Configuration for "static voice bridge" feature.
2679
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_static_voice_bridge_shown()) {
2680
        $renderer->render_group_header('voicebridge');
2681
        $renderer->render_group_element('voicebridge_editable',
2682
            $renderer->render_group_element_checkbox('voicebridge_editable', 0));
2683
    }
2684
}
2685
2686
/**
2687
 * Helper function renders preuploaded presentation settings if the feature is enabled.
2688
 *
2689
 * @param object $renderer
2690
 *
2691
 * @return void
2692
 */
2693
function bigbluebuttonbn_settings_preupload(&$renderer) {
2694
    // Configuration for "preupload presentation" feature.
2695
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_preupload_presentation_shown()) {
2696
        // This feature only works if curl is installed.
2697
        $preuploaddescripion = get_string('config_preuploadpresentation_description', 'bigbluebuttonbn');
2698
        if (!extension_loaded('curl')) {
2699
            $preuploaddescripion .= '<div class="form-defaultinfo">';
2700
            $preuploaddescripion .= get_string('config_warning_curl_not_installed', 'bigbluebuttonbn');
2701
            $preuploaddescripion .= '</div><br>';
2702
        }
2703
        $renderer->render_group_header('preuploadpresentation', null, $preuploaddescripion);
2704
        if (extension_loaded('curl')) {
2705
            $renderer->render_group_element('preuploadpresentation_enabled',
2706
                $renderer->render_group_element_checkbox('preuploadpresentation_enabled', 0));
2707
        }
2708
    }
2709
}
2710
2711
/**
2712
 * Helper function renders preuploaded presentation manage file if the feature is enabled.
2713
 * This allow to select a file for use as default in all BBB instances if preuploaded presetantion is enable.
2714
 *
2715
 * @param object $renderer
2716
 *
2717
 * @return void
2718
 */
2719
function bigbluebuttonbn_settings_preupload_manage_default_file(&$renderer) {
2720
    // Configuration for "preupload presentation" feature.
2721
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_preupload_presentation_shown()) {
2722
        if (extension_loaded('curl')) {
2723
            // This feature only works if curl is installed.
2724
            $renderer->render_filemanager_default_file_presentation("presentation_default");
2725
        }
2726
    }
2727
}
2728
2729
/**
2730
 * Helper function renders userlimit settings if the feature is enabled.
2731
 *
2732
 * @param object $renderer
2733
 *
2734
 * @return void
2735
 */
2736
function bigbluebuttonbn_settings_userlimit(&$renderer) {
2737
    // Configuration for "user limit" feature.
2738
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_user_limit_shown()) {
2739
        $renderer->render_group_header('userlimit');
2740
        $renderer->render_group_element('userlimit_default',
2741
            $renderer->render_group_element_text('userlimit_default', 0, PARAM_INT));
2742
        $renderer->render_group_element('userlimit_editable',
2743
            $renderer->render_group_element_checkbox('userlimit_editable', 0));
2744
    }
2745
}
2746
2747
/**
2748
 * Helper function renders duration settings if the feature is enabled.
2749
 *
2750
 * @param object $renderer
2751
 *
2752
 * @return void
2753
 */
2754
function bigbluebuttonbn_settings_duration(&$renderer) {
2755
    // Configuration for "scheduled duration" feature.
2756
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_scheduled_duration_shown()) {
2757
        $renderer->render_group_header('scheduled');
2758
        $renderer->render_group_element('scheduled_duration_enabled',
2759
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1));
2760
        $renderer->render_group_element('scheduled_duration_compensation',
2761
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT));
2762
        $renderer->render_group_element('scheduled_pre_opening',
2763
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT));
2764
    }
2765
}
2766
2767
/**
2768
 * Helper function renders participant settings if the feature is enabled.
2769
 *
2770
 * @param object $renderer
2771
 *
2772
 * @return void
2773
 */
2774
function bigbluebuttonbn_settings_participants(&$renderer) {
2775
    // Configuration for defining the default role/user that will be moderator on new activities.
2776
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_moderator_default_shown()) {
2777
        $renderer->render_group_header('participant');
2778
        // UI for 'participants' feature.
2779
        $roles = bigbluebuttonbn_get_roles(null, false);
2780
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2781
        $renderer->render_group_element('participant_moderator_default',
2782
            $renderer->render_group_element_configmultiselect(
2783
                'participant_moderator_default',
2784
                array_keys($owner),
2785
                $owner + $roles) // CONTRIB-7966: don't use array_merge here so it does not reindex the array.
2786
          );
2787
    }
2788
}
2789
2790
/**
2791
 * Helper function renders notification settings if the feature is enabled.
2792
 *
2793
 * @param object $renderer
2794
 *
2795
 * @return void
2796
 */
2797
function bigbluebuttonbn_settings_notifications(&$renderer) {
2798
    // Configuration for "send notifications" feature.
2799
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_send_notifications_shown()) {
2800
        $renderer->render_group_header('sendnotifications');
2801
        $renderer->render_group_element('sendnotifications_enabled',
2802
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1));
2803
    }
2804
}
2805
2806
/**
2807
 * Helper function renders client type settings if the feature is enabled.
2808
 *
2809
 * @param object $renderer
2810
 *
2811
 * @return void
2812
 */
2813
function bigbluebuttonbn_settings_clienttype(&$renderer) {
2814
    // Configuration for "clienttype" feature.
2815
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_clienttype_shown()) {
2816
        $renderer->render_group_header('clienttype');
2817
        $renderer->render_group_element('clienttype_editable',
2818
            $renderer->render_group_element_checkbox('clienttype_editable', 0));
2819
        // Web Client default.
2820
        $default = intval((int)\mod_bigbluebuttonbn\locallib\config::get('clienttype_default'));
2821
        $choices = array(BIGBLUEBUTTON_CLIENTTYPE_FLASH => get_string('mod_form_block_clienttype_flash', 'bigbluebuttonbn'),
2822
                         BIGBLUEBUTTON_CLIENTTYPE_HTML5 => get_string('mod_form_block_clienttype_html5', 'bigbluebuttonbn'));
2823
        $renderer->render_group_element('clienttype_default',
2824
            $renderer->render_group_element_configselect('clienttype_default',
2825
                $default, $choices));
2826
    }
2827
}
2828
2829
/**
2830
 * Helper function renders general settings if the feature is enabled.
2831
 *
2832
 * @param object $renderer
2833
 *
2834
 * @return void
2835
 */
2836 View Code Duplication
function bigbluebuttonbn_settings_muteonstart(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2837
    // Configuration for BigBlueButton.
2838
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_muteonstart_shown()) {
2839
        $renderer->render_group_header('muteonstart');
2840
        $renderer->render_group_element('muteonstart_default',
2841
            $renderer->render_group_element_checkbox('muteonstart_default', 0));
2842
        $renderer->render_group_element('muteonstart_editable',
2843
            $renderer->render_group_element_checkbox('muteonstart_editable', 0));
2844
    }
2845
}
2846
2847
/**
2848
 * Helper function renders extended settings if any of the features there is enabled.
2849
 *
2850
 * @param object $renderer
2851
 *
2852
 * @return void
2853
 */
2854 View Code Duplication
function bigbluebuttonbn_settings_extended(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2855
    // Configuration for 'notify users when recording ready' feature.
2856
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_settings_extended_shown()) {
2857
        $renderer->render_group_header('extended_capabilities');
2858
        // UI for 'notify users when recording ready' feature.
2859
        $renderer->render_group_element('recordingready_enabled',
2860
            $renderer->render_group_element_checkbox('recordingready_enabled', 0));
2861
        // Configuration for extended BN capabilities.
2862
        if (bigbluebuttonbn_is_bn_server()) {
2863
            // UI for 'register meeting events' feature.
2864
            $renderer->render_group_element('meetingevents_enabled',
2865
                $renderer->render_group_element_checkbox('meetingevents_enabled', 0));
2866
        }
2867
    }
2868
}
2869
2870
/**
2871
 * Helper function returns a sha1 encoded string that is unique and will be used as a seed for meetingid.
2872
 *
2873
 * @return string
2874
 */
2875
function bigbluebuttonbn_unique_meetingid_seed() {
2876
    global $DB;
2877
    do {
2878
        $encodedseed = sha1(bigbluebuttonbn_random_password(12));
2879
        $meetingid = (string)$DB->get_field('bigbluebuttonbn', 'meetingid', array('meetingid' => $encodedseed));
2880
    } while ($meetingid == $encodedseed);
2881
    return $encodedseed;
2882
}
2883
2884
/**
2885
 * Helper function renders the link used for recording type in row for the data used by the recording table.
2886
 *
2887
 * @param array $recording
2888
 * @param array $bbbsession
2889
 * @param array $playback
2890
 *
2891
 * @return boolean
2892
 */
2893
function bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback) {
2894
    // All types that are not restricted are included.
2895
    if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'false') {
2896
        return true;
2897
    }
2898
    // All types that are not statistics are included.
2899
    if ($playback['type'] != 'statistics') {
2900
        return true;
2901
    }
2902
    // Exclude imported recordings.
2903
    if (isset($recording['imported'])) {
2904
        return false;
2905
    }
2906
    // Exclude non moderators.
2907
    if (!$bbbsession['administrator'] && !$bbbsession['moderator']) {
2908
        return false;
2909
    }
2910
    return true;
2911
}
2912
2913
/**
2914
 * Renders the general warning message.
2915
 *
2916
 * @param string $message
2917
 * @param string $type
2918
 * @param string $href
2919
 * @param string $text
2920
 * @param string $class
2921
 *
2922
 * @return string
2923
 */
2924
function bigbluebuttonbn_render_warning($message, $type='info', $href='', $text='', $class='') {
2925
    global $OUTPUT;
2926
    $output = "\n";
2927
    // Evaluates if config_warning is enabled.
2928
    if (empty($message)) {
2929
        return $output;
2930
    }
2931
    $output .= $OUTPUT->box_start('box boxalignleft adminerror alert alert-' . $type . ' alert-block fade in',
2932
      'bigbluebuttonbn_view_general_warning') . "\n";
2933
    $output .= '    ' . $message . "\n";
2934
    $output .= '  <div class="singlebutton pull-right">' . "\n";
2935
    if (!empty($href)) {
2936
        $output .= bigbluebuttonbn_render_warning_button($href, $text, $class);
2937
    }
2938
    $output .= '  </div>' . "\n";
2939
    $output .= $OUTPUT->box_end() . "\n";
2940
    return $output;
2941
}
2942
2943
/**
2944
 * Renders the general warning button.
2945
 *
2946
 * @param string $href
2947
 * @param string $text
2948
 * @param string $class
2949
 * @param string $title
2950
 *
2951
 * @return string
2952
 */
2953
function bigbluebuttonbn_render_warning_button($href, $text = '', $class = '', $title = '') {
2954
    if ($text == '') {
2955
        $text = get_string('ok', 'moodle');
2956
    }
2957
    if ($title == '') {
2958
        $title = $text;
2959
    }
2960
    if ($class == '') {
2961
        $class = 'btn btn-secondary';
2962
    }
2963
    $output  = '  <form method="post" action="' . $href . '" class="form-inline">'."\n";
2964
    $output .= '      <button type="submit" class="' . $class . '"'."\n";
2965
    $output .= '          title="' . $title . '"'."\n";
2966
    $output .= '          >' . $text . '</button>'."\n";
2967
    $output .= '  </form>'."\n";
2968
    return $output;
2969
}
2970
2971
/**
2972
 * Check if a BigBlueButtonBN is available to be used by the current user.
2973
 *
2974
 * @param  stdClass  $bigbluebuttonbn  BigBlueButtonBN instance
2975
 *
2976
 * @return boolean                     status if room available and current user allowed to join
2977
 */
2978
function bigbluebuttonbn_get_availability_status($bigbluebuttonbn) {
2979
    list($roomavailable) = bigbluebuttonbn_room_is_available($bigbluebuttonbn);
2980
    list($usercanjoin) = bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn);
2981
2982
    return ($roomavailable && $usercanjoin);
2983
}
2984
2985
/**
2986
 * Helper for evaluating if scheduled activity is avaiable.
2987
 *
2988
 * @param  stdClass  $bigbluebuttonbn  BigBlueButtonBN instance
2989
 *
2990
 * @return array                       status (room available or not and possible warnings)
2991
 */
2992
function bigbluebuttonbn_room_is_available($bigbluebuttonbn) {
2993
    $open = true;
2994
    $closed = false;
2995
    $warnings = array();
2996
2997
    $timenow = time();
2998
    $timeopen = $bigbluebuttonbn->openingtime;
2999
    $timeclose = $bigbluebuttonbn->closingtime;
3000
    if (!empty($timeopen) && $timeopen > $timenow) {
3001
        $open = false;
3002
    }
3003
    if (!empty($timeclose) && $timenow > $timeclose) {
3004
        $closed = true;
3005
    }
3006
3007
    if (!$open || $closed) {
3008
        if (!$open) {
3009
            $warnings['notopenyet'] = userdate($timeopen);
3010
        }
3011
        if ($closed) {
3012
            $warnings['expired'] = userdate($timeclose);
3013
        }
3014
        return array(false, $warnings);
3015
    }
3016
3017
    return array(true, $warnings);
3018
}
3019
3020
/**
3021
 * Helper for evaluating if meeting can be joined.
3022
 *
3023
 * @param  stdClass $bigbluebuttonbn  BigBlueButtonBN instance
3024
 * @param  string   $mid
3025
 * @param  integer  $userid
3026
 *
3027
 * @return array    status (user allowed to join or not and possible message)
3028
 */
3029
function bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn, $mid = null, $userid = null) {
3030
3031
    // By default, use a meetingid without groups.
3032
    if (empty($mid)) {
3033
        $mid = $bigbluebuttonbn->meetingid . '-' . $bigbluebuttonbn->course . '-' . $bigbluebuttonbn->id;
3034
    }
3035
3036
    // When meeting is running, all authorized users can join right in.
3037
    if (bigbluebuttonbn_is_meeting_running($mid)) {
3038
        return array(true, get_string('view_message_conference_in_progress', 'bigbluebuttonbn'));
3039
    }
3040
3041
    // When meeting is not running, see if the user can join.
3042
    $context = context_course::instance($bigbluebuttonbn->course);
3043
    $participantlist = bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context);
3044
    $isadmin = is_siteadmin($userid);
3045
    $ismoderator = bigbluebuttonbn_is_moderator($context, $participantlist, $userid);
3046
    // If user is administrator, moderator or if is viewer and no waiting is required, join allowed.
3047
    if ($isadmin || $ismoderator || !$bigbluebuttonbn->wait) {
3048
        return array(true, get_string('view_message_conference_room_ready', 'bigbluebuttonbn'));
3049
    }
3050
    // Otherwise, no join allowed.
3051
    return array(false, get_string('view_message_conference_wait_for_moderator', 'bigbluebuttonbn'));
3052
}
3053
3054
/**
3055
 * Helper for getting a value from a bigbluebuttonbn cache.
3056
 *
3057
 * @param  string   $name       BigBlueButtonBN cache
3058
 * @param  string   $key        Key to be retrieved
3059
 * @param  integer  $default    Default value in case key is not found or it is empty
3060
 *
3061
 * @return variable key value
3062
 */
3063
function bigbluebuttonbn_cache_get($name, $key, $default = null) {
3064
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', $name);
3065
    $result = $cache->get($key);
3066
    if (!empty($result)) {
3067
        return $result;
3068
    }
3069
    return $default;
3070
}
3071
3072
/**
3073
 * Helper for setting a value in a bigbluebuttonbn cache.
3074
 *
3075
 * @param  string   $name       BigBlueButtonBN cache
3076
 * @param  string   $key        Key to be created/updated
3077
 * @param  variable $value      Default value to be set
3078
 */
3079
function bigbluebuttonbn_cache_set($name, $key, $value) {
3080
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', $name);
3081
    $cache->set($key, $value);
3082
}
3083
3084
/**
3085
 * Helper for getting the owner userid of a bigbluebuttonbn instance.
3086
 *
3087
 * @param  stdClass $bigbluebuttonbn  BigBlueButtonBN instance
3088
 *
3089
 * @return integer ownerid (a valid user id or null if not registered/found)
3090
 */
3091
function bigbluebuttonbn_instance_ownerid($bigbluebuttonbn) {
3092
    global $DB;
3093
    $filters = array('bigbluebuttonbnid' => $bigbluebuttonbn->id, 'log' => 'Add');
3094
    $ownerid = (integer)$DB->get_field('bigbluebuttonbn_logs', 'userid', $filters);
3095
    return $ownerid;
3096
}
3097
3098
/**
3099
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
3100
 *
3101
 * @return boolean
3102
 */
3103
function bigbluebuttonbn_has_html5_client() {
3104
    $checkurl = \mod_bigbluebuttonbn\locallib\bigbluebutton::root() . "html5client/check";
3105
    $curlinfo = bigbluebuttonbn_wrap_xml_load_file_curl_request($checkurl, 'HEAD');
3106
    return (isset($curlinfo['http_code']) && $curlinfo['http_code'] == 200);
3107
}
3108
3109
/**
3110
 * Setup the bbbsession variable that is used all accross the plugin.
3111
 *
3112
 * @param object $context
3113
 * @param array $bbbsession
3114
 * @return void
3115
 */
3116 View Code Duplication
function bigbluebuttonbn_view_bbbsession_set($context, &$bbbsession) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
3117
    global $CFG, $USER;
3118
    // User data.
3119
    $bbbsession['username'] = fullname($USER);
3120
    $bbbsession['userID'] = $USER->id;
3121
    // User roles.
3122
    $bbbsession['administrator'] = is_siteadmin($bbbsession['userID']);
3123
    $participantlist = bigbluebuttonbn_get_participant_list($bbbsession['bigbluebuttonbn'], $context);
3124
    $bbbsession['moderator'] = bigbluebuttonbn_is_moderator($context, $participantlist);
3125
    $bbbsession['managerecordings'] = ($bbbsession['administrator']
3126
        || has_capability('mod/bigbluebuttonbn:managerecordings', $context));
3127
    $bbbsession['importrecordings'] = ($bbbsession['managerecordings']);
3128
    // Server data.
3129
    $bbbsession['modPW'] = $bbbsession['bigbluebuttonbn']->moderatorpass;
3130
    $bbbsession['viewerPW'] = $bbbsession['bigbluebuttonbn']->viewerpass;
3131
    // Database info related to the activity.
3132
    $bbbsession['meetingid'] = $bbbsession['bigbluebuttonbn']->meetingid.'-'.$bbbsession['course']->id.'-'.
3133
        $bbbsession['bigbluebuttonbn']->id;
3134
    $bbbsession['meetingname'] = $bbbsession['bigbluebuttonbn']->name;
3135
    $bbbsession['meetingdescription'] = $bbbsession['bigbluebuttonbn']->intro;
3136
    // Extra data for setting up the Meeting.
3137
    $bbbsession['userlimit'] = intval((int)\mod_bigbluebuttonbn\locallib\config::get('userlimit_default'));
3138
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::get('userlimit_editable')) {
3139
        $bbbsession['userlimit'] = intval($bbbsession['bigbluebuttonbn']->userlimit);
3140
    }
3141
    $bbbsession['voicebridge'] = $bbbsession['bigbluebuttonbn']->voicebridge;
3142
    if ($bbbsession['bigbluebuttonbn']->voicebridge > 0) {
3143
        $bbbsession['voicebridge'] = 70000 + $bbbsession['bigbluebuttonbn']->voicebridge;
3144
    }
3145
    $bbbsession['wait'] = $bbbsession['bigbluebuttonbn']->wait;
3146
    $bbbsession['record'] = $bbbsession['bigbluebuttonbn']->record;
3147
    $bbbsession['recordallfromstart'] = $CFG->bigbluebuttonbn_recording_all_from_start_default;
3148
    if ($CFG->bigbluebuttonbn_recording_all_from_start_editable) {
3149
        $bbbsession['recordallfromstart'] = $bbbsession['bigbluebuttonbn']->recordallfromstart;
3150
    }
3151
    $bbbsession['recordhidebutton'] = $CFG->bigbluebuttonbn_recording_hide_button_default;
3152
    if ($CFG->bigbluebuttonbn_recording_hide_button_editable) {
3153
        $bbbsession['recordhidebutton'] = $bbbsession['bigbluebuttonbn']->recordhidebutton;
3154
    }
3155
    $bbbsession['welcome'] = $bbbsession['bigbluebuttonbn']->welcome;
3156
    if (!isset($bbbsession['welcome']) || $bbbsession['welcome'] == '') {
3157
        $bbbsession['welcome'] = get_string('mod_form_field_welcome_default', 'bigbluebuttonbn');
3158
    }
3159
    if ($bbbsession['bigbluebuttonbn']->record) {
3160
        // Check if is enable record all from start.
3161
        if ($bbbsession['recordallfromstart']) {
3162
            $bbbsession['welcome'] .= '<br><br>'.get_string('bbbrecordallfromstartwarning',
3163
                    'bigbluebuttonbn');
3164
        } else {
3165
            $bbbsession['welcome'] .= '<br><br>'.get_string('bbbrecordwarning', 'bigbluebuttonbn');
3166
        }
3167
    }
3168
    $bbbsession['openingtime'] = $bbbsession['bigbluebuttonbn']->openingtime;
3169
    $bbbsession['closingtime'] = $bbbsession['bigbluebuttonbn']->closingtime;
3170
    $bbbsession['muteonstart'] = $bbbsession['bigbluebuttonbn']->muteonstart;
3171
    // Additional info related to the course.
3172
    $bbbsession['context'] = $context;
3173
    // Metadata (origin).
3174
    $bbbsession['origin'] = 'Moodle';
3175
    $bbbsession['originVersion'] = $CFG->release;
3176
    $parsedurl = parse_url($CFG->wwwroot);
3177
    $bbbsession['originServerName'] = $parsedurl['host'];
3178
    $bbbsession['originServerUrl'] = $CFG->wwwroot;
3179
    $bbbsession['originServerCommonName'] = '';
3180
    $bbbsession['originTag'] = 'moodle-mod_bigbluebuttonbn ('.get_config('mod_bigbluebuttonbn', 'version').')';
3181
    $bbbsession['bnserver'] = bigbluebuttonbn_is_bn_server();
3182
    // Setting for clienttype, assign flash if not enabled, or default if not editable.
3183
    $bbbsession['clienttype'] = BIGBLUEBUTTON_CLIENTTYPE_FLASH;
3184
    if (\mod_bigbluebuttonbn\locallib\config::clienttype_enabled()) {
3185
        $bbbsession['clienttype'] = \mod_bigbluebuttonbn\locallib\config::get('clienttype_default');
3186
    }
3187
    if (\mod_bigbluebuttonbn\locallib\config::get('clienttype_editable') && isset($bbbsession['bigbluebuttonbn']->clienttype)) {
3188
        $bbbsession['clienttype'] = $bbbsession['bigbluebuttonbn']->clienttype;
3189
    }
3190
}
3191
3192
/**
3193
 * Return the status of an activity [open|not_started|ended].
3194
 *
3195
 * @param array $bbbsession
3196
 * @return string
3197
 */
3198 View Code Duplication
function bigbluebuttonbn_view_get_activity_status(&$bbbsession) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
3199
    $now = time();
3200
    if (!empty($bbbsession['bigbluebuttonbn']->openingtime) && $now < $bbbsession['bigbluebuttonbn']->openingtime) {
3201
        // The activity has not been opened.
3202
        return 'not_started';
3203
    }
3204
    if (!empty($bbbsession['bigbluebuttonbn']->closingtime) && $now > $bbbsession['bigbluebuttonbn']->closingtime) {
3205
        // The activity has been closed.
3206
        return 'ended';
3207
    }
3208
    // The activity is open.
3209
    return 'open';
3210
}
3211
3212
/**
3213
 * Set session URLs.
3214
 *
3215
 * @param array $bbbsession
3216
 * @param int $id
3217
 * @return string
3218
 */
3219
function bigbluebuttonbn_view_session_config(&$bbbsession, $id) {
3220
    // Operation URLs.
3221
    $bbbsession['bigbluebuttonbnURL'] = plugin::necurl(
3222
        '/mod/bigbluebuttonbn/view.php', ['id' => $bbbsession['cm']->id]
3223
    );
3224
    $bbbsession['logoutURL'] = plugin::necurl(
3225
        '/mod/bigbluebuttonbn/bbb_view.php',
3226
        ['action' => 'logout', 'id' => $id, 'bn' => $bbbsession['bigbluebuttonbn']->id]
3227
    );
3228
    $bbbsession['recordingReadyURL'] = plugin::necurl(
3229
        '/mod/bigbluebuttonbn/bbb_broker.php',
3230
        ['action' => 'recording_ready', 'bigbluebuttonbn' => $bbbsession['bigbluebuttonbn']->id]
3231
    );
3232
    $bbbsession['meetingEventsURL'] = plugin::necurl(
3233
        '/mod/bigbluebuttonbn/bbb_broker.php',
3234
        ['action' => 'meeting_events', 'bigbluebuttonbn' => $bbbsession['bigbluebuttonbn']->id]
3235
    );
3236
    $bbbsession['joinURL'] = plugin::necurl(
3237
        '/mod/bigbluebuttonbn/bbb_view.php',
3238
        ['action' => 'join', 'id' => $id, 'bn' => $bbbsession['bigbluebuttonbn']->id]
3239
    );
3240
3241
    // Check status and set extra values.
3242
    $activitystatus = bigbluebuttonbn_view_get_activity_status($bbbsession);  // In locallib.
3243 View Code Duplication
    if ($activitystatus == 'ended') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
3244
        $bbbsession['presentation'] = bigbluebuttonbn_get_presentation_array(
3245
            $bbbsession['context'], $bbbsession['bigbluebuttonbn']->presentation);
3246
    } else if ($activitystatus == 'open') {
3247
        $bbbsession['presentation'] = bigbluebuttonbn_get_presentation_array(
3248
            $bbbsession['context'], $bbbsession['bigbluebuttonbn']->presentation, $bbbsession['bigbluebuttonbn']->id);
3249
    }
3250
3251
    return $activitystatus;
3252
}
3253