Completed
Push — master ( ab9e22...72dffb )
by Jesus
02:17
created

locallib.php ➔ bigbluebuttonbn_cache_get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

    return array();
}

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

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

Loading history...
190
    // Sort recordings.
191
    uasort($recordings, 'bigbluebuttonbn_recording_build_sorter');
192
    // Filter recordings based on recordingIDs.
193
    $recordingidsarray = $recordingids;
194
    if (!is_array($recordingids)) {
195
        $recordingidsarray = explode(',', $recordingids);
196
    }
197
    if (empty($recordingidsarray)) {
198
        // No recording ids, no need to filter.
199
        return $recordings;
200
    }
201
    return bigbluebuttonbn_get_recordings_array_filter($recordingidsarray, $recordings);
0 ignored issues
show
Bug introduced by
It seems like $recordingidsarray defined by $recordingids on line 193 can also be of type string; however, bigbluebuttonbn_get_recordings_array_filter() does only seem to accept array, maybe add an additional type check?

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

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

    return array();
}

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

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

Loading history...
202
}
203
204
/**
205
 * Helper function to fetch recordings from a BigBlueButton server.
206
 *
207
 * @param array $meetingidsarray   array with meeting ids in the form array("mid1","mid2","mid3")
208
 *
209
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
210
 */
211
function bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray) {
212
    $recordings = array();
213
    // Execute a paginated getRecordings request.
214
    $pages = floor(count($meetingidsarray) / 25) + 1;
215
    for ($page = 1; $page <= $pages; ++$page) {
216
        $mids = array_slice($meetingidsarray, ($page - 1) * 25, 25);
217
        $recordings += bigbluebuttonbn_get_recordings_array_fetch_page($mids);
218
    }
219
    return $recordings;
220
}
221
222
/**
223
 * Helper function to fetch one page of upto 25 recordings from a BigBlueButton server.
224
 *
225
 * @param array  $mids
226
 *
227
 * @return array
228
 */
229
function bigbluebuttonbn_get_recordings_array_fetch_page($mids) {
230
    $recordings = array();
231
    // Do getRecordings is executed using a method GET (supported by all versions of BBB).
232
    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings', ['meetingID' => implode(',', $mids)]);
233
    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
234
    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
235
        // If there were meetings already created.
236
        foreach ($xml->recordings->recording as $recordingxml) {
237
            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
238
            $recordings[$recording['recordID']] = $recording;
239
        }
240
    }
241
    return $recordings;
242
}
243
244
/**
245
 * Helper function to remove a set of recordings from an array.
246
 *
247
 * @param array  $rids
248
 * @param array  $recordings
249
 *
250
 * @return array
251
 */
252
function bigbluebuttonbn_get_recordings_array_filter($rids, &$recordings) {
253
    foreach ($recordings as $key => $recording) {
254
        if (!in_array($recording['recordID'], $rids)) {
255
            unset($recordings[$key]);
256
        }
257
    }
258
    return $recordings;
259
}
260
261
/**
262
 * Helper function to retrieve imported recordings from the Moodle database.
263
 * The references are stored as events in bigbluebuttonbn_logs.
264
 *
265
 * @param string $courseid
266
 * @param string $bigbluebuttonbnid
267
 * @param bool   $subset
268
 *
269
 * @return associative array with imported recordings indexed by recordID, each recording
270
 * is a non sequential associative array that corresponds to the actual recording in BBB
271
 */
272
function bigbluebuttonbn_get_recordings_imported_array($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
273
    global $DB;
274
    $select = bigbluebuttonbn_get_recordings_imported_sql_select($courseid, $bigbluebuttonbnid, $subset);
275
    $recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select);
276
    $recordsimportedarray = array();
277
    foreach ($recordsimported as $recordimported) {
278
        $meta = json_decode($recordimported->meta, true);
279
        $recording = $meta['recording'];
280
        // Override imported flag with actual ID.
281
        $recording['imported'] = $recordimported->id;
282
        if (isset($recordimported->protected)) {
283
            $recording['protected'] = (string) $recordimported->protected;
284
        }
285
        $recordsimportedarray[$recording['recordID']] = $recording;
286
    }
287
    return $recordsimportedarray;
288
}
289
290
/**
291
 * Helper function to retrive the default config.xml file.
292
 *
293
 * @return string
294
 */
295
function bigbluebuttonbn_get_default_config_xml() {
296
    $xml = bigbluebuttonbn_wrap_xml_load_file(
297
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getDefaultConfigXML')
298
      );
299
    return $xml;
300
}
301
302
/**
303
 * Helper function to convert an xml recording object to an array in the format used by the plugin.
304
 *
305
 * @param object $recording
306
 *
307
 * @return array
308
 */
309
function bigbluebuttonbn_get_recording_array_value($recording) {
310
    // Add formats.
311
    $playbackarray = array();
312
    foreach ($recording->playback->format as $format) {
313
        $playbackarray[(string) $format->type] = array('type' => (string) $format->type,
314
            'url' => trim((string) $format->url), 'length' => (string) $format->length);
315
        // Add preview per format when existing.
316
        if ($format->preview) {
317
            $playbackarray[(string) $format->type]['preview'] = bigbluebuttonbn_get_recording_preview_images($format->preview);
318
        }
319
    }
320
    // Add the metadata to the recordings array.
321
    $metadataarray = bigbluebuttonbn_get_recording_array_meta(get_object_vars($recording->metadata));
322
    $recordingarray = array('recordID' => (string) $recording->recordID,
323
        'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
324
        'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
325
        'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray);
326
    if (isset($recording->protected)) {
327
        $recordingarray['protected'] = (string) $recording->protected;
328
    }
329
    return $recordingarray + $metadataarray;
330
}
331
332
/**
333
 * Helper function to convert an xml recording preview images to an array in the format used by the plugin.
334
 *
335
 * @param object $preview
336
 *
337
 * @return array
338
 */
339
function bigbluebuttonbn_get_recording_preview_images($preview) {
340
    $imagesarray = array();
341
    foreach ($preview->images->image as $image) {
342
        $imagearray = array('url' => trim((string) $image));
343
        foreach ($image->attributes() as $attkey => $attvalue) {
344
            $imagearray[$attkey] = (string) $attvalue;
345
        }
346
        array_push($imagesarray, $imagearray);
347
    }
348
    return $imagesarray;
349
}
350
351
/**
352
 * Helper function to convert an xml recording metadata object to an array in the format used by the plugin.
353
 *
354
 * @param array $metadata
355
 *
356
 * @return array
357
 */
358
function bigbluebuttonbn_get_recording_array_meta($metadata) {
359
    $metadataarray = array();
360
    foreach ($metadata as $key => $value) {
361
        if (is_object($value)) {
362
            $value = '';
363
        }
364
        $metadataarray['meta_'.$key] = $value;
365
    }
366
    return $metadataarray;
367
}
368
369
/**
370
 * Helper function to sort an array of recordings. It compares the startTime in two recording objecs.
371
 *
372
 * @param object $a
373
 * @param object $b
374
 *
375
 * @return array
376
 */
377
function bigbluebuttonbn_recording_build_sorter($a, $b) {
378
    if ($a['startTime'] < $b['startTime']) {
379
        return -1;
380
    }
381
    if ($a['startTime'] == $b['startTime']) {
382
        return 0;
383
    }
384
    return 1;
385
}
386
387
/**
388
 * Perform deleteRecordings on BBB.
389
 *
390
 * @param string $recordids
391
 *
392
 * @return boolean
393
 */
394 View Code Duplication
function bigbluebuttonbn_delete_recordings($recordids) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
395
    $ids = explode(',', $recordids);
396
    foreach ($ids as $id) {
397
        $xml = bigbluebuttonbn_wrap_xml_load_file(
398
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('deleteRecordings', ['recordID' => $id])
399
          );
400
        if ($xml && $xml->returncode != 'SUCCESS') {
401
            return false;
402
        }
403
    }
404
    return true;
405
}
406
407
/**
408
 * Perform publishRecordings on BBB.
409
 *
410
 * @param string $recordids
411
 * @param string $publish
412
 */
413 View Code Duplication
function bigbluebuttonbn_publish_recordings($recordids, $publish = 'true') {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
414
    $ids = explode(',', $recordids);
415
    foreach ($ids as $id) {
416
        $xml = bigbluebuttonbn_wrap_xml_load_file(
417
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish])
418
          );
419
        if ($xml && $xml->returncode != 'SUCCESS') {
420
            return false;
421
        }
422
    }
423
    return true;
424
}
425
426
/**
427
 * Perform updateRecordings on BBB.
428
 *
429
 * @param string $recordids
430
 * @param array $params ['key'=>param_key, 'value']
431
 */
432 View Code Duplication
function bigbluebuttonbn_update_recordings($recordids, $params) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
433
    $ids = explode(',', $recordids);
434
    foreach ($ids as $id) {
435
        $xml = bigbluebuttonbn_wrap_xml_load_file(
436
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('updateRecordings', ['recordID' => $id] + (array) $params)
437
          );
438
        if ($xml && $xml->returncode != 'SUCCESS') {
439
            return false;
440
        }
441
    }
442
    return true;
443
}
444
445
/**
446
 * Perform end on BBB.
447
 *
448
 * @param string $meetingid
449
 * @param string $modpw
450
 */
451
function bigbluebuttonbn_end_meeting($meetingid, $modpw) {
452
    $xml = bigbluebuttonbn_wrap_xml_load_file(
453
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('end', ['meetingID' => $meetingid, 'password' => $modpw])
454
      );
455
    if ($xml) {
456
        // If the xml packet returned failure it displays the message to the user.
457
        return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
458
    }
459
    // If the server is unreachable, then prompts the user of the necessary action.
460
    return null;
461
}
462
463
/**
464
 * Perform api request on BBB.
465
 *
466
 * @return string
467
 */
468
function bigbluebuttonbn_get_server_version() {
469
    $xml = bigbluebuttonbn_wrap_xml_load_file(
470
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url()
471
      );
472
    if ($xml && $xml->returncode == 'SUCCESS') {
473
        return $xml->version;
474
    }
475
    return null;
476
}
477
478
/**
479
 * Perform api request on BBB and wraps the response in an XML object
480
 *
481
 * @param string $url
482
 * @param string $method
483
 * @param string $data
484
 * @param string $contenttype
485
 *
486
 * @return object
487
 */
488
function bigbluebuttonbn_wrap_xml_load_file($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
489
    if (extension_loaded('curl')) {
490
        $response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype);
491
        if (!$response) {
492
            debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER);
493
            return null;
494
        }
495
        $previous = libxml_use_internal_errors(true);
496
        try {
497
            $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
498
            return $xml;
499
        } catch (Exception $e) {
500
            libxml_use_internal_errors($previous);
501
            $error = 'Caught exception: '.$e->getMessage();
502
            debugging($error, DEBUG_DEVELOPER);
503
            return null;
504
        }
505
    }
506
    // Alternative request non CURL based.
507
    $previous = libxml_use_internal_errors(true);
508
    try {
509
        $response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
510
        return $response;
511
    } catch (Exception $e) {
512
        $error = 'Caught exception: '.$e->getMessage();
513
        debugging($error, DEBUG_DEVELOPER);
514
        libxml_use_internal_errors($previous);
515
        return null;
516
    }
517
}
518
519
/**
520
 * Perform api request on BBB using CURL 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_curl_request($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
530
    $c = new curl();
531
    $c->setopt(array('SSL_VERIFYPEER' => true));
532
    if ($method == 'POST') {
533
        if (is_null($data) || is_array($data)) {
534
            return $c->post($url);
535
        }
536
        $options = array();
537
        $options['CURLOPT_HTTPHEADER'] = array(
538
                 'Content-Type: '.$contenttype,
539
                 'Content-Length: '.strlen($data),
540
                 'Content-Language: en-US',
541
               );
542
543
        return $c->post($url, $data, $options);
544
    }
545
    if ($method == 'HEAD') {
546
        $c->head($url, array('followlocation' => true, 'timeout' => 1));
547
        return $c->get_info();
548
    }
549
    return $c->get($url);
550
}
551
552
/**
553
 * End the session associated with this instance (if it's running).
554
 *
555
 * @param object $bigbluebuttonbn
556
 *
557
 * @return void
558
 */
559
function bigbluebuttonbn_end_meeting_if_running($bigbluebuttonbn) {
560
    $meetingid = $bigbluebuttonbn->meetingid.'-'.$bigbluebuttonbn->course.'-'.$bigbluebuttonbn->id;
561
    if (bigbluebuttonbn_is_meeting_running($meetingid)) {
562
        bigbluebuttonbn_end_meeting($meetingid, $bigbluebuttonbn->moderatorpass);
563
    }
564
}
565
566
/**
567
 * Returns user roles in a context.
568
 *
569
 * @param object $context
570
 * @param integer $userid
571
 *
572
 * @return array $userroles
573
 */
574
function bigbluebuttonbn_get_user_roles($context, $userid) {
575
    global $DB;
576
    $userroles = get_user_roles($context, $userid);
577
    if ($userroles) {
578
        $where = '';
579
        foreach ($userroles as $userrole) {
580
            $where .= (empty($where) ? ' WHERE' : ' OR').' id=' . $userrole->roleid;
581
        }
582
        $userroles = $DB->get_records_sql('SELECT * FROM {role}'.$where);
583
    }
584
    return $userroles;
585
}
586
587
/**
588
 * Returns guest role wrapped in an array.
589
 *
590
 * @return array
591
 */
592
function bigbluebuttonbn_get_guest_role() {
593
    $guestrole = get_guest_role();
594
    return array($guestrole->id => $guestrole);
595
}
596
597
/**
598
 * Returns an array containing all the users in a context.
599
 *
600
 * @param context $context
601
 *
602
 * @return array $users
603
 */
604
function bigbluebuttonbn_get_users(context $context = null) {
605
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
606
    foreach ($users as $key => $value) {
607
        $users[$key] = fullname($value);
608
    }
609
    return $users;
610
}
611
612
/**
613
 * Returns an array containing all the users in a context wrapped for html select element.
614
 *
615
 * @param context $context
616
 *
617
 * @return array $users
618
 */
619
function bigbluebuttonbn_get_users_select(context $context = null) {
620
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
621
    foreach ($users as $key => $value) {
622
        $users[$key] = array('id' => $value->id, 'name' => fullname($value));
623
    }
624
    return $users;
625
}
626
627
/**
628
 * Returns an array containing all the roles in a context.
629
 *
630
 * @param context $context
631
 *
632
 * @return array $roles
633
 */
634
function bigbluebuttonbn_get_roles(context $context = null) {
635
    $roles = (array) role_get_names($context);
636
    foreach ($roles as $key => $value) {
637
        $roles[$key] = $value->localname;
638
    }
639
    return $roles;
640
}
641
642
/**
643
 * Returns an array containing all the roles in a context wrapped for html select element.
644
 *
645
 * @param context $context
646
 *
647
 * @return array $users
648
 */
649
function bigbluebuttonbn_get_roles_select(context $context = null) {
650
    $roles = (array) role_get_names($context);
651
    foreach ($roles as $key => $value) {
652
        $roles[$key] = array('id' => $value->id, 'name' => $value->localname);
653
    }
654
    return $roles;
655
}
656
657
/**
658
 * Returns role that corresponds to an id.
659
 *
660
 * @param string|integer $id
661
 *
662
 * @return object $role
663
 */
664
function bigbluebuttonbn_get_role($id) {
665
    $roles = (array) role_get_names();
666
    if (is_numeric($id) && isset($roles[$id])) {
667
        return (object)$roles[$id];
668
    }
669
    foreach ($roles as $role) {
670
        if ($role->shortname == $id) {
671
            return $role;
672
        }
673
    }
674
}
675
676
/**
677
 * Returns an array to populate a list of participants used in mod_form.js.
678
 *
679
 * @param context $context
680
 *
681
 * @return array $data
682
 */
683
function bigbluebuttonbn_get_participant_data($context) {
684
    $data = array(
685
        'all' => array(
686
            'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
687
            'children' => []
688
          )
689
      );
690
    $data['role'] = array(
691
        'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
692
        'children' => bigbluebuttonbn_get_roles_select($context)
693
      );
694
    $data['user'] = array(
695
        'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
696
        'children' => bigbluebuttonbn_get_users_select($context)
697
      );
698
    return $data;
699
}
700
701
/**
702
 * Returns an array to populate a list of participants used in mod_form.php.
703
 *
704
 * @param object $bigbluebuttonbn
705
 * @param context $context
706
 *
707
 * @return array
708
 */
709
function bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context) {
710
    global $USER;
711
    if ($bigbluebuttonbn == null) {
712
        return bigbluebuttonbn_get_participant_rules_encoded(
713
            bigbluebuttonbn_get_participant_list_default($context, $USER->id)
714
        );
715
    }
716
    if (empty($bigbluebuttonbn->participants)) {
717
        $bigbluebuttonbn->participants = "[]";
718
    }
719
    $rules = json_decode($bigbluebuttonbn->participants, true);
720
    if (empty($rules)) {
721
        $rules = bigbluebuttonbn_get_participant_list_default($context, bigbluebuttonbn_instance_ownerid($bigbluebuttonbn));
722
    }
723
    return bigbluebuttonbn_get_participant_rules_encoded($rules);
724
}
725
726
/**
727
 * Returns an array to populate a list of participants used in mod_form.php with default values.
728
 *
729
 * @param context $context
730
 * @param integer $ownerid
731
 *
732
 * @return array
733
 */
734
function bigbluebuttonbn_get_participant_list_default($context, $ownerid = null) {
735
    $participantlist = array();
736
    $participantlist[] = array(
737
        'selectiontype' => 'all',
738
        'selectionid' => 'all',
739
        'role' => BIGBLUEBUTTONBN_ROLE_VIEWER
740
      );
741
    $defaultrules = explode(',', \mod_bigbluebuttonbn\locallib\config::get('participant_moderator_default'));
742
    foreach ($defaultrules as $defaultrule) {
743
        if ($defaultrule == '0') {
744
            if (!empty($ownerid) && is_enrolled($context, $ownerid)) {
745
                $participantlist[] = array(
746
                    'selectiontype' => 'user',
747
                    'selectionid' => (string)$ownerid,
748
                    'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
749
            }
750
            continue;
751
        }
752
        $participantlist[] = array(
753
              'selectiontype' => 'role',
754
              'selectionid' => $defaultrule,
755
              'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
756
    }
757
    return $participantlist;
758
}
759
760
/**
761
 * Returns an array to populate a list of participants used in mod_form.php with bigbluebuttonbn values.
762
 *
763
 * @param array $rules
764
 *
765
 * @return array
766
 */
767
function bigbluebuttonbn_get_participant_rules_encoded($rules) {
768
    foreach ($rules as $key => $rule) {
769
        if ($rule['selectiontype'] !== 'role' || is_numeric($rule['selectionid'])) {
770
            continue;
771
        }
772
        $role = bigbluebuttonbn_get_role($rule['selectionid']);
773
        if ($role == null) {
774
            unset($rules[$key]);
775
            continue;
776
        }
777
        $rule['selectionid'] = $role->id;
778
        $rules[$key] = $rule;
779
    }
780
    return $rules;
781
}
782
783
/**
784
 * Returns an array to populate a list of participant_selection used in mod_form.php.
785
 *
786
 * @return array
787
 */
788
function bigbluebuttonbn_get_participant_selection_data() {
789
    return [
790
        'type_options' => [
791
            'all' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
792
            'role' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
793
            'user' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
794
          ],
795
        'type_selected' => 'all',
796
        'options' => ['all' => '---------------'],
797
        'selected' => 'all',
798
      ];
799
}
800
801
/**
802
 * Evaluate if a user in a context is moderator based on roles and participation rules.
803
 *
804
 * @param context $context
805
 * @param array $participantlist
806
 * @param integer $userid
807
 *
808
 * @return boolean
809
 */
810
function bigbluebuttonbn_is_moderator($context, $participantlist, $userid = null) {
811
    global $USER;
812
    if (!is_array($participantlist)) {
813
        return false;
814
    }
815
    if (empty($userid)) {
816
        $userid = $USER->id;
817
    }
818
    $userroles = bigbluebuttonbn_get_guest_role();
819
    if (!isguestuser()) {
820
        $userroles = bigbluebuttonbn_get_user_roles($context, $userid);
821
    }
822
    return bigbluebuttonbn_is_moderator_validator($participantlist, $userid , $userroles);
823
}
824
825
/**
826
 * Iterates participant list rules to evaluate if a user is moderator.
827
 *
828
 * @param array $participantlist
829
 * @param integer $userid
830
 * @param array $userroles
831
 *
832
 * @return boolean
833
 */
834
function bigbluebuttonbn_is_moderator_validator($participantlist, $userid, $userroles) {
835
    // Iterate participant rules.
836
    foreach ($participantlist as $participant) {
837
        if (bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles)) {
838
            return true;
839
        }
840
    }
841
    return false;
842
}
843
844
/**
845
 * Evaluate if a user is moderator based on roles and a particular participation rule.
846
 *
847
 * @param object $participant
848
 * @param integer $userid
849
 * @param array $userroles
850
 *
851
 * @return boolean
852
 */
853
function bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles) {
854
    if ($participant['role'] == BIGBLUEBUTTONBN_ROLE_VIEWER) {
855
        return false;
856
    }
857
    // Looks for all configuration.
858
    if ($participant['selectiontype'] == 'all') {
859
        return true;
860
    }
861
    // Looks for users.
862
    if ($participant['selectiontype'] == 'user' && $participant['selectionid'] == $userid) {
863
        return true;
864
    }
865
    // Looks for roles.
866
    $role = bigbluebuttonbn_get_role($participant['selectionid']);
867
    if ($role != null && array_key_exists($role->id, $userroles)) {
868
        return true;
869
    }
870
    return false;
871
}
872
873
/**
874
 * Helper returns error message key for the language file that corresponds to a bigbluebutton error key.
875
 *
876
 * @param string $messagekey
877
 * @param string $defaultkey
878
 *
879
 * @return string
880
 */
881
function bigbluebuttonbn_get_error_key($messagekey, $defaultkey = null) {
882
    if ($messagekey == 'checksumError') {
883
        return 'index_error_checksum';
884
    }
885
    if ($messagekey == 'maxConcurrent') {
886
        return 'view_error_max_concurrent';
887
    }
888
    return $defaultkey;
889
}
890
891
/**
892
 * Helper evaluates if a voicebridge number is unique.
893
 *
894
 * @param integer $instance
895
 * @param integer $voicebridge
896
 *
897
 * @return string
898
 */
899
function bigbluebuttonbn_voicebridge_unique($instance, $voicebridge) {
900
    global $DB;
901
    if ($voicebridge == 0) {
902
        return true;
903
    }
904
    $select = 'voicebridge = ' . $voicebridge;
905
    if ($instance != 0) {
906
        $select .= ' AND id <>' . $instance;
907
    }
908
    if (!$DB->get_records_select('bigbluebuttonbn', $select)) {
909
        return true;
910
    }
911
    return false;
912
}
913
914
/**
915
 * Helper estimate a duration for the meeting based on the closingtime.
916
 *
917
 * @param integer $closingtime
918
 *
919
 * @return integer
920
 */
921
function bigbluebuttonbn_get_duration($closingtime) {
922
    $duration = 0;
923
    $now = time();
924
    if ($closingtime > 0 && $now < $closingtime) {
925
        $duration = ceil(($closingtime - $now) / 60);
926
        $compensationtime = intval((int)\mod_bigbluebuttonbn\locallib\config::get('scheduled_duration_compensation'));
927
        $duration = intval($duration) + $compensationtime;
928
    }
929
    return $duration;
930
}
931
932
/**
933
 * Helper return array containing the file descriptor for a preuploaded presentation.
934
 *
935
 * @param context $context
936
 * @param string $presentation
937
 * @param integer $id
938
 *
939
 * @return array
940
 */
941
function bigbluebuttonbn_get_presentation_array($context, $presentation, $id = null) {
942
    if (empty($presentation)) {
943
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
944
    }
945
    $fs = get_file_storage();
946
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
947
        'itemid, filepath, filename', false);
948
    if (count($files) == 0) {
949
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
950
    }
951
    $file = reset($files);
952
    unset($files);
953
    $pnoncevalue = null;
954
    if (!is_null($id)) {
955
        // Create the nonce component for granting a temporary public access.
956
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn',
957
            'presentation_cache');
958
        $pnoncekey = sha1($id);
959
        /* The item id was adapted for granting public access to the presentation once in order
960
         * to allow BigBlueButton to gather the file. */
961
        $pnoncevalue = bigbluebuttonbn_generate_nonce();
962
        $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
963
    }
964
    $url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
965
        $file->get_filearea(), $pnoncevalue, $file->get_filepath(), $file->get_filename());
966
    return array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
967
            'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file));
968
}
969
970
/**
971
 * Helper generates a nonce used for the preuploaded presentation callback url.
972
 *
973
 * @return string
974
 */
975
function bigbluebuttonbn_generate_nonce() {
976
    $mt = microtime();
977
    $rand = mt_rand();
978
    return md5($mt.$rand);
979
}
980
981
/**
982
 * Helper generates a random password.
983
 *
984
 * @param integer $length
985
 * @param string $unique
986
 *
987
 * @return string
988
 */
989
function bigbluebuttonbn_random_password($length = 8, $unique = "") {
990
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?';
991
    do {
992
        $password = substr(str_shuffle($chars), 0, $length);
993
    } while ($unique == $password);
994
    return $password;
995
}
996
997
/**
998
 * Helper register a bigbluebuttonbn event.
999
 *
1000
 * @param string $type
1001
 * @param object $bigbluebuttonbn
1002
 * @param array $options [timecreated, userid, other]
1003
 *
1004
 * @return void
1005
 */
1006
function bigbluebuttonbn_event_log($type, $bigbluebuttonbn, $options = []) {
1007
    global $DB;
1008
    if (!in_array($type, \mod_bigbluebuttonbn\event\events::$events)) {
1009
        // No log will be created.
1010
        return;
1011
    }
1012
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
1013
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
1014
    $context = context_module::instance($cm->id);
1015
    $params = array('context' => $context, 'objectid' => $bigbluebuttonbn->id);
1016
    if (array_key_exists('timecreated', $options)) {
1017
        $params['timecreated'] = $options['timecreated'];
1018
    }
1019
    if (array_key_exists('userid', $options)) {
1020
        $params['userid'] = $options['userid'];
1021
    }
1022
    if (array_key_exists('other', $options)) {
1023
        $params['other'] = $options['other'];
1024
    }
1025
    $event = call_user_func_array('\mod_bigbluebuttonbn\event\\' . $type . '::create',
1026
        array($params));
1027
    $event->add_record_snapshot('course_modules', $cm);
1028
    $event->add_record_snapshot('course', $course);
1029
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
1030
    $event->trigger();
1031
}
1032
1033
/**
1034
 * Updates the meeting info cached object when a participant has joined.
1035
 *
1036
 * @param string $meetingid
1037
 * @param bool $ismoderator
1038
 *
1039
 * @return void
1040
 */
1041
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) {
1042
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1043
    $result = $cache->get($meetingid);
1044
    $meetinginfo = json_decode($result['meeting_info']);
1045
    $meetinginfo->participantCount += 1;
1046
    if ($ismoderator) {
1047
        $meetinginfo->moderatorCount += 1;
1048
    }
1049
    $cache->set($meetingid, array('creation_time' => $result['creation_time'],
1050
        'meeting_info' => json_encode($meetinginfo)));
1051
}
1052
1053
/**
1054
 * Gets a meeting info object cached or fetched from the live session.
1055
 *
1056
 * @param string $meetingid
1057
 * @param boolean $updatecache
1058
 *
1059
 * @return array
1060
 */
1061
function bigbluebuttonbn_get_meeting_info($meetingid, $updatecache = false) {
1062
    $cachettl = (int)\mod_bigbluebuttonbn\locallib\config::get('waitformoderator_cache_ttl');
1063
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1064
    $result = $cache->get($meetingid);
1065
    $now = time();
1066
    if (!$updatecache && isset($result) && $now < ($result['creation_time'] + $cachettl)) {
1067
        // Use the value in the cache.
1068
        return (array) json_decode($result['meeting_info']);
1069
    }
1070
    // Ping again and refresh the cache.
1071
    $meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file(
1072
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
1073
      );
1074
    $cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo)));
1075
    return $meetinginfo;
1076
}
1077
1078
/**
1079
 * Perform isMeetingRunning on BBB.
1080
 *
1081
 * @param string $meetingid
1082
 * @param boolean $updatecache
1083
 *
1084
 * @return boolean
1085
 */
1086
function bigbluebuttonbn_is_meeting_running($meetingid, $updatecache = false) {
1087
    /* As a workaround to isMeetingRunning that always return SUCCESS but only returns true
1088
     * when at least one user is in the session, we use getMeetingInfo instead.
1089
     */
1090
    $meetinginfo = bigbluebuttonbn_get_meeting_info($meetingid, $updatecache);
1091
    return ($meetinginfo['returncode'] === 'SUCCESS');
1092
}
1093
1094
/**
1095
 * Publish an imported recording.
1096
 *
1097
 * @param string $id
1098
 * @param boolean $publish
1099
 *
1100
 * @return boolean
1101
 */
1102 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...
1103
    global $DB;
1104
    // Locate the record to be updated.
1105
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1106
    $meta = json_decode($record->meta, true);
1107
    // Prepare data for the update.
1108
    $meta['recording']['published'] = ($publish) ? 'true' : 'false';
1109
    $record->meta = json_encode($meta);
1110
    // Proceed with the update.
1111
    $DB->update_record('bigbluebuttonbn_logs', $record);
1112
    return true;
1113
}
1114
1115
/**
1116
 * Delete an imported recording.
1117
 *
1118
 * @param string $id
1119
 *
1120
 * @return boolean
1121
 */
1122
function bigbluebuttonbn_delete_recording_imported($id) {
1123
    global $DB;
1124
    // Execute delete.
1125
    $DB->delete_records('bigbluebuttonbn_logs', array('id' => $id));
1126
    return true;
1127
}
1128
1129
/**
1130
 * Update an imported recording.
1131
 *
1132
 * @param string $id
1133
 * @param array $params ['key'=>param_key, 'value']
1134
 *
1135
 * @return boolean
1136
 */
1137
function bigbluebuttonbn_update_recording_imported($id, $params) {
1138
    global $DB;
1139
    // Locate the record to be updated.
1140
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1141
    $meta = json_decode($record->meta, true);
1142
    // Prepare data for the update.
1143
    $meta['recording'] = $params + $meta['recording'];
1144
    $record->meta = json_encode($meta);
1145
    // Proceed with the update.
1146
    if (!$DB->update_record('bigbluebuttonbn_logs', $record)) {
1147
        return false;
1148
    }
1149
    return true;
1150
}
1151
1152
/**
1153
 * Protect/Unprotect an imported recording.
1154
 *
1155
 * @param string $id
1156
 * @param boolean $protect
1157
 *
1158
 * @return boolean
1159
 */
1160 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...
1161
    global $DB;
1162
    // Locate the record to be updated.
1163
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1164
    $meta = json_decode($record->meta, true);
1165
    // Prepare data for the update.
1166
    $meta['recording']['protected'] = ($protect) ? 'true' : 'false';
1167
    $record->meta = json_encode($meta);
1168
    // Proceed with the update.
1169
    $DB->update_record('bigbluebuttonbn_logs', $record);
1170
    return true;
1171
}
1172
1173
/**
1174
 * Sets a custom config.xml file for being used on create.
1175
 *
1176
 * @param string $meetingid
1177
 * @param string $configxml
1178
 *
1179
 * @return object
1180
 */
1181
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) {
1182
    $urldefaultconfig = \mod_bigbluebuttonbn\locallib\config::get('server_url').'api/setConfigXML?';
1183
    $configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml);
1184
    $xml = bigbluebuttonbn_wrap_xml_load_file($urldefaultconfig, 'POST',
1185
        $configxmlparams, 'application/x-www-form-urlencoded');
1186
    return $xml;
1187
}
1188
1189
/**
1190
 * Sets qs used with a custom config.xml file request.
1191
 *
1192
 * @param string $meetingid
1193
 * @param string $configxml
1194
 *
1195
 * @return string
1196
 */
1197
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) {
1198
    $params = 'configXML='.urlencode($configxml).'&meetingID='.urlencode($meetingid);
1199
    $configxmlparams = $params.'&checksum='.sha1('setConfigXML'.$params.\mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
1200
    return $configxmlparams;
1201
}
1202
1203
/**
1204
 * Sets a custom config.xml file for being used on create.
1205
 *
1206
 * @param string $meetingid
1207
 * @param string $configxml
1208
 *
1209
 * @return array
1210
 */
1211
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) {
1212
    $configxml = bigbluebuttonbn_setConfigXML($meetingid, $configxml);
1213
    $configxmlarray = (array) $configxml;
1214
    if ($configxmlarray['returncode'] != 'SUCCESS') {
1215
        debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER);
1216
        return '';
1217
    }
1218
    return $configxmlarray['configToken'];
1219
}
1220
1221
/**
1222
 * Helper function builds a row for the data used by the recording table.
1223
 *
1224
 * @param array $bbbsession
1225
 * @param array $recording
1226
 * @param array $tools
1227
 *
1228
 * @return array
1229
 */
1230
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['protect', 'publish', 'delete']) {
1231
    if (!bigbluebuttonbn_include_recording_table_row($bbbsession, $recording)) {
1232
        return;
1233
    }
1234
    $rowdata = new stdClass();
1235
    // Set recording_types.
1236
    $rowdata->recording = bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession);
1237
    // Set activity name.
1238
    $rowdata->activity = bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession);
1239
    // Set activity description.
1240
    $rowdata->description = bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession);
1241
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1242
        // Set recording_preview.
1243
        $rowdata->preview = bigbluebuttonbn_get_recording_data_row_preview($recording);
1244
    }
1245
    // Set date.
1246
    $rowdata->date = bigbluebuttonbn_get_recording_data_row_date($recording);
1247
    // Set formatted date.
1248
    $rowdata->date_formatted = bigbluebuttonbn_get_recording_data_row_date_formatted($rowdata->date);
1249
    // Set formatted duration.
1250
    $rowdata->duration_formatted = $rowdata->duration = bigbluebuttonbn_get_recording_data_row_duration($recording);
1251
    // Set actionbar, if user is allowed to manage recordings.
1252
    if ($bbbsession['managerecordings']) {
1253
        $rowdata->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools);
1254
    }
1255
    return $rowdata;
1256
}
1257
1258
/**
1259
 * Helper function evaluates if a row for the data used by the recording table is editable.
1260
 *
1261
 * @param array $bbbsession
1262
 *
1263
 * @return boolean
1264
 */
1265
function bigbluebuttonbn_get_recording_data_row_editable($bbbsession) {
1266
    return ($bbbsession['managerecordings'] && ((double)$bbbsession['serverversion'] >= 1.0 || $bbbsession['bnserver']));
1267
}
1268
1269
/**
1270
 * Helper function evaluates if recording preview should be included.
1271
 *
1272
 * @param array $bbbsession
1273
 *
1274
 * @return boolean
1275
 */
1276
function bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession) {
1277
    return ((double)$bbbsession['serverversion'] >= 1.0 && $bbbsession['bigbluebuttonbn']->recordings_preview == '1');
1278
}
1279
1280
/**
1281
 * Helper function converts recording date used in row for the data used by the recording table.
1282
 *
1283
 * @param array $recording
1284
 *
1285
 * @return integer
1286
 */
1287
function bigbluebuttonbn_get_recording_data_row_date($recording) {
1288
    if (!isset($recording['startTime'])) {
1289
        return 0;
1290
    }
1291
    return floatval($recording['startTime']);
1292
}
1293
1294
/**
1295
 * Helper function format recording date used in row for the data used by the recording table.
1296
 *
1297
 * @param integer $starttime
1298
 *
1299
 * @return string
1300
 */
1301
function bigbluebuttonbn_get_recording_data_row_date_formatted($starttime) {
1302
    global $USER;
1303
    $starttime = $starttime - ($starttime % 1000);
1304
    // Set formatted date.
1305
    $dateformat = get_string('strftimerecentfull', 'langconfig').' %Z';
1306
    return userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone));
1307
}
1308
1309
/**
1310
 * Helper function converts recording duration used in row for the data used by the recording table.
1311
 *
1312
 * @param array $recording
1313
 *
1314
 * @return integer
1315
 */
1316
function bigbluebuttonbn_get_recording_data_row_duration($recording) {
1317
    foreach (array_values($recording['playbacks']) as $playback) {
1318
        // Ignore restricted playbacks.
1319
        if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'true') {
1320
            continue;
1321
        }
1322
        // Take the lenght form the fist playback with an actual value.
1323
        if (!empty($playback['length'])) {
1324
            return intval($playback['length']);
1325
        }
1326
    }
1327
    return 0;
1328
}
1329
1330
/**
1331
 * Helper function builds recording actionbar used in row for the data used by the recording table.
1332
 *
1333
 * @param array $recording
1334
 * @param array $tools
1335
 *
1336
 * @return string
1337
 */
1338
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) {
1339
    $actionbar = '';
1340
    foreach ($tools as $tool) {
1341
        $buttonpayload = bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool);
1342
        if ($tool == 'protect') {
1343
            if (isset($recording['imported'])) {
1344
                $buttonpayload['disabled'] = 'disabled';
1345
            }
1346
            if (!isset($recording['protected'])) {
1347
                $buttonpayload['disabled'] = 'invisible';
1348
            }
1349
        }
1350
        $actionbar .= bigbluebuttonbn_actionbar_render_button($recording, $buttonpayload);
1351
    }
1352
    $head = html_writer::start_tag('div', array(
1353
        'id' => 'recording-actionbar-' . $recording['recordID'],
1354
        'data-recordingid' => $recording['recordID'],
1355
        'data-meetingid' => $recording['meetingID']));
1356
    $tail = html_writer::end_tag('div');
1357
    return $head . $actionbar . $tail;
1358
}
1359
1360
/**
1361
 * Helper function returns the corresponding payload for an actionbar button used in row
1362
 * for the data used by the recording table.
1363
 *
1364
 * @param array $recording
1365
 * @param array $tool
1366
 *
1367
 * @return array
1368
 */
1369
function bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool) {
1370
    if ($tool == 'protect') {
1371
        $protected = 'false';
1372
        if (isset($recording['protected'])) {
1373
            $protected = $recording['protected'];
1374
        }
1375
        return bigbluebuttonbn_get_recording_data_row_action_protect($protected);
1376
    }
1377
    if ($tool == 'publish') {
1378
        return bigbluebuttonbn_get_recording_data_row_action_publish($recording['published']);
1379
    }
1380
    return array('action' => $tool, 'tag' => $tool);
1381
}
1382
1383
/**
1384
 * Helper function returns the payload for protect action button used in row
1385
 * for the data used by the recording table.
1386
 *
1387
 * @param string $protected
1388
 *
1389
 * @return array
1390
 */
1391
function bigbluebuttonbn_get_recording_data_row_action_protect($protected) {
1392
    if ($protected == 'true') {
1393
        return array('action' => 'unprotect', 'tag' => 'lock');
1394
    }
1395
    return array('action' => 'protect', 'tag' => 'unlock');
1396
}
1397
1398
/**
1399
 * Helper function returns the payload for publish action button used in row
1400
 * for the data used by the recording table.
1401
 *
1402
 * @param string $published
1403
 *
1404
 * @return array
1405
 */
1406
function bigbluebuttonbn_get_recording_data_row_action_publish($published) {
1407
    if ($published == 'true') {
1408
        return array('action' => 'unpublish', 'tag' => 'hide');
1409
    }
1410
    return array('action' => 'publish', 'tag' => 'show');
1411
}
1412
1413
/**
1414
 * Helper function builds recording preview used in row for the data used by the recording table.
1415
 *
1416
 * @param array $recording
1417
 *
1418
 * @return string
1419
 */
1420
function bigbluebuttonbn_get_recording_data_row_preview($recording) {
1421
    $options = array('id' => 'preview-'.$recording['recordID']);
1422
    if ($recording['published'] === 'false') {
1423
        $options['hidden'] = 'hidden';
1424
    }
1425
    $recordingpreview = html_writer::start_tag('div', $options);
1426
    foreach ($recording['playbacks'] as $playback) {
1427
        if (isset($playback['preview'])) {
1428
            $recordingpreview .= bigbluebuttonbn_get_recording_data_row_preview_images($playback);
1429
            break;
1430
        }
1431
    }
1432
    $recordingpreview .= html_writer::end_tag('div');
1433
    return $recordingpreview;
1434
}
1435
1436
/**
1437
 * Helper function builds element with actual images used in recording preview row based on a selected playback.
1438
 *
1439
 * @param array $playback
1440
 *
1441
 * @return string
1442
 */
1443
function bigbluebuttonbn_get_recording_data_row_preview_images($playback) {
1444
    $recordingpreview  = html_writer::start_tag('div', array('class' => 'container-fluid'));
1445
    $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1446
    foreach ($playback['preview'] as $image) {
1447
        if (!bigbluebuttonbn_is_valid_resource(trim($image['url']))) {
1448
            return '';
1449
        }
1450
        $recordingpreview .= html_writer::start_tag('div', array('class' => ''));
1451
        $recordingpreview .= html_writer::empty_tag('img',
1452
            array('src' => trim($image['url']) . '?' . time(), 'class' => 'recording-thumbnail pull-left'));
1453
        $recordingpreview .= html_writer::end_tag('div');
1454
    }
1455
    $recordingpreview .= html_writer::end_tag('div');
1456
    $recordingpreview .= html_writer::start_tag('div', array('class' => 'row'));
1457
    $recordingpreview .= html_writer::tag('div', get_string('view_recording_preview_help', 'bigbluebuttonbn'),
1458
        array('class' => 'text-center text-muted small'));
1459
    $recordingpreview .= html_writer::end_tag('div');
1460
    $recordingpreview .= html_writer::end_tag('div');
1461
    return $recordingpreview;
1462
}
1463
1464
/**
1465
 * Helper function renders recording types to be used in row for the data used by the recording table.
1466
 *
1467
 * @param array $recording
1468
 * @param array $bbbsession
1469
 *
1470
 * @return string
1471
 */
1472
function bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession) {
1473
    $dataimported = 'false';
1474
    $title = '';
1475
    if (isset($recording['imported'])) {
1476
        $dataimported = 'true';
1477
        $title = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1478
    }
1479
    $visibility = '';
1480
    if ($recording['published'] === 'false') {
1481
        $visibility = 'hidden ';
1482
    }
1483
    $id = 'playbacks-'.$recording['recordID'];
1484
    $recordingtypes = html_writer::start_tag('div', array('id' => $id, 'data-imported' => $dataimported,
1485
          'data-meetingid' => $recording['meetingID'], 'data-recordingid' => $recording['recordID'],
1486
          'title' => $title, $visibility => $visibility));
1487
    foreach ($recording['playbacks'] as $playback) {
1488
        $recordingtypes .= bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback);
1489
    }
1490
    $recordingtypes .= html_writer::end_tag('div');
1491
    return $recordingtypes;
1492
}
1493
1494
/**
1495
 * Helper function renders the link used for recording type in row for the data used by the recording table.
1496
 *
1497
 * @param array $recording
1498
 * @param array $bbbsession
1499
 * @param array $playback
1500
 *
1501
 * @return string
1502
 */
1503
function bigbluebuttonbn_get_recording_data_row_type($recording, $bbbsession, $playback) {
1504
    global $CFG, $OUTPUT;
1505
    if (!bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback)) {
1506
        return '';
1507
    }
1508
    $text = get_string('view_recording_format_'.$playback['type'], 'bigbluebuttonbn');
1509
    $href = $CFG->wwwroot . '/mod/bigbluebuttonbn/bbb_view.php?action=play&bn=' . $bbbsession['bigbluebuttonbn']->id .
1510
      '&mid='.$recording['meetingID'] . '&rid=' . $recording['recordID'] . '&rtype=' . $playback['type'];
1511
    if (!isset($recording['imported']) || !isset($recording['protected']) || $recording['protected'] === 'false') {
1512
        $href .= '&href='.urlencode(trim($playback['url']));
1513
    }
1514
    $linkattributes = array(
1515
        'id' => 'recording-play-' . $playback['type'] . '-' . $recording['recordID'],
1516
        'class' => 'btn btn-sm btn-default',
1517
        'onclick' => 'M.mod_bigbluebuttonbn.recordings.recordingPlay(this);',
1518
        'data-action' => 'play',
1519
        'data-target' => $playback['type'],
1520
        'data-href' => $href,
1521
      );
1522
    if (!bigbluebuttonbn_is_bn_server() && !bigbluebuttonbn_is_valid_resource(trim($playback['url']))) {
1523
        $linkattributes['class'] = 'btn btn-sm btn-warning';
1524
        $linkattributes['title'] = get_string('view_recording_format_errror_unreachable', 'bigbluebuttonbn');
1525
        unset($linkattributes['data-href']);
1526
    }
1527
    return $OUTPUT->action_link('#', $text, null, $linkattributes) . '&#32;';
1528
}
1529
1530
/**
1531
 * Helper function validates a remote resource.
1532
 *
1533
 * @param string $url
1534
 *
1535
 * @return boolean
1536
 */
1537
function bigbluebuttonbn_is_valid_resource($url) {
1538
    $urlhost = parse_url($url, PHP_URL_HOST);
1539
    $serverurlhost = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'), PHP_URL_HOST);
1540
    // Skip validation when the recording URL host is the same as the configured BBB server.
1541
    if ($urlhost == $serverurlhost) {
1542
        return true;
1543
    }
1544
    // Skip validation when the recording URL was already validated.
1545
    $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...
1546
    if (array_key_exists($urlhost, $validatedurls)) {
1547
        return $validatedurls[$urlhost];
1548
    }
1549
    // Validate the recording URL.
1550
    $validatedurls[$urlhost] = true;
1551
    $curlinfo = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, 'HEAD');
1552
    if (!isset($curlinfo['http_code']) || $curlinfo['http_code'] != 200) {
1553
        $error = "Resources hosted by " . $urlhost . " are unreachable. Server responded with code " . $curlinfo['http_code'];
1554
        debugging($error, DEBUG_DEVELOPER);
1555
        $validatedurls[$urlhost] = false;
1556
    }
1557
    bigbluebuttonbn_cache_set('recordings_cache', 'validated_urls', $validatedurls);
1558
    return $validatedurls[$urlhost];
1559
}
1560
1561
/**
1562
 * Helper function renders the name for recording used in row for the data used by the recording table.
1563
 *
1564
 * @param array $recording
1565
 * @param array $bbbsession
1566
 *
1567
 * @return string
1568
 */
1569
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $bbbsession) {
1570
    $payload = array();
1571 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...
1572
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1573
            'action' => 'edit', 'tag' => 'edit',
1574
            'target' => 'name');
1575
    }
1576
    $oldsource = 'meta_contextactivity';
1577
    if (isset($recording[$oldsource])) {
1578
        $metaname = trim($recording[$oldsource]);
1579
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $oldsource, $payload);
1580
    }
1581
    $newsource = 'meta_bbb-recording-name';
1582 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...
1583
        $metaname = trim($recording[$newsource]);
1584
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1585
    }
1586
    $metaname = trim($recording['meetingName']);
1587
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1588
}
1589
1590
/**
1591
 * Helper function renders the description for recording used in row for the data used by the recording table.
1592
 *
1593
 * @param array $recording
1594
 * @param array $bbbsession
1595
 *
1596
 * @return string
1597
 */
1598
function bigbluebuttonbn_get_recording_data_row_meta_description($recording, $bbbsession) {
1599
    $payload = array();
1600 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...
1601
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1602
            'action' => 'edit', 'tag' => 'edit',
1603
            'target' => 'description');
1604
    }
1605
    $oldsource = 'meta_contextactivitydescription';
1606 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...
1607
        $metadescription = trim($recording[$oldsource]);
1608
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $oldsource, $payload);
1609
    }
1610
    $newsource = 'meta_bbb-recording-description';
1611 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...
1612
        $metadescription = trim($recording[$newsource]);
1613
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $newsource, $payload);
1614
    }
1615
    return bigbluebuttonbn_get_recording_data_row_text($recording, '', $newsource, $payload);
1616
}
1617
1618
/**
1619
 * Helper function renders text element for recording used in row for the data used by the recording table.
1620
 *
1621
 * @param array $recording
1622
 * @param string $text
1623
 * @param string $source
1624
 * @param array $data
1625
 *
1626
 * @return string
1627
 */
1628
function bigbluebuttonbn_get_recording_data_row_text($recording, $text, $source, $data) {
1629
    $htmltext = '<span>' . htmlentities($text) . '</span>';
1630
    if (empty($data)) {
1631
        return $htmltext;
1632
    }
1633
    $target = $data['action'] . '-' . $data['target'];
1634
    $id = 'recording-' . $target . '-' . $data['recordingid'];
1635
    $attributes = array('id' => $id, 'class' => 'quickeditlink col-md-20',
1636
        'data-recordingid' => $data['recordingid'], 'data-meetingid' => $data['meetingid'],
1637
        'data-target' => $data['target'], 'data-source' => $source);
1638
    $head = html_writer::start_tag('div', $attributes);
1639
    $tail = html_writer::end_tag('div');
1640
    $payload = array('action' => $data['action'], 'tag' => $data['tag'], 'target' => $data['target']);
1641
    $htmllink = bigbluebuttonbn_actionbar_render_button($recording, $payload);
1642
    return $head . $htmltext . $htmllink . $tail;
1643
}
1644
1645
/**
1646
 * Helper function render a button for the recording action bar
1647
 *
1648
 * @param array $recording
1649
 * @param array $data
1650
 *
1651
 * @return string
1652
 */
1653
function bigbluebuttonbn_actionbar_render_button($recording, $data) {
1654
    global $OUTPUT;
1655
    if (empty($data)) {
1656
        return '';
1657
    }
1658
    $target = $data['action'];
1659
    if (isset($data['target'])) {
1660
        $target .= '-' . $data['target'];
1661
    }
1662
    $id = 'recording-' . $target . '-' . $recording['recordID'];
1663
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recording' . ucfirst($data['action']) . '(this);';
1664
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::get('recording_icons_enabled')) {
1665
        // With icon for $manageaction.
1666
        $iconattributes = array('id' => $id, 'class' => 'iconsmall');
1667
        $linkattributes = array(
1668
            'id' => $id,
1669
            'onclick' => $onclick,
1670
            'data-action' => $data['action']
1671
          );
1672
        if (!isset($recording['imported'])) {
1673
            $linkattributes['data-links'] = bigbluebuttonbn_count_recording_imported_instances(
1674
              $recording['recordID']);
1675
        }
1676
        if (isset($data['disabled'])) {
1677
            $iconattributes['class'] .= ' fa-' . $data['disabled'];
1678
            $linkattributes['class'] = 'disabled';
1679
            unset($linkattributes['onclick']);
1680
        }
1681
        $icon = new pix_icon('i/'.$data['tag'],
1682
            get_string('view_recording_list_actionbar_' . $data['action'], 'bigbluebuttonbn'),
1683
            'moodle', $iconattributes);
1684
        return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false);
1685
    }
1686
    // With text for $manageaction.
1687
    $linkattributes = array('title' => get_string($data['tag']), 'class' => 'btn btn-xs btn-danger',
1688
        'onclick' => $onclick);
1689
    return $OUTPUT->action_link('#', get_string($data['action']), null, $linkattributes);
1690
}
1691
1692
/**
1693
 * Helper function builds the data used for headers by the recording table.
1694
 *
1695
 * @param array $bbbsession
1696
 *
1697
 * @return array
1698
 */
1699
function bigbluebuttonbn_get_recording_columns($bbbsession) {
1700
    $columns = array();
1701
    // Initialize table headers.
1702
    $columns[] = array('key' => 'recording', 'label' => get_string('view_recording_recording', 'bigbluebuttonbn'),
1703
        'width' => '125px', 'allowHTML' => true);
1704
    $columns[] = array('key' => 'activity', 'label' => get_string('view_recording_activity', 'bigbluebuttonbn'),
1705
        'sortable' => true, 'width' => '175px', 'allowHTML' => true);
1706
    $columns[] = array('key' => 'description', 'label' => get_string('view_recording_description', 'bigbluebuttonbn'),
1707
        'sortable' => true, 'width' => '250px', 'allowHTML' => true);
1708
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1709
        $columns[] = array('key' => 'preview', 'label' => get_string('view_recording_preview', 'bigbluebuttonbn'),
1710
            'width' => '250px', 'allowHTML' => true);
1711
    }
1712
    $columns[] = array('key' => 'date', 'label' => get_string('view_recording_date', 'bigbluebuttonbn'),
1713
        'sortable' => true, 'width' => '225px', 'allowHTML' => true);
1714
    $columns[] = array('key' => 'duration', 'label' => get_string('view_recording_duration', 'bigbluebuttonbn'),
1715
        'width' => '50px');
1716
    if ($bbbsession['managerecordings']) {
1717
        $columns[] = array('key' => 'actionbar', 'label' => get_string('view_recording_actionbar', 'bigbluebuttonbn'),
1718
            'width' => '120px', 'allowHTML' => true);
1719
    }
1720
    return $columns;
1721
}
1722
1723
/**
1724
 * Helper function builds the data used by the recording table.
1725
 *
1726
 * @param array $bbbsession
1727
 * @param array $recordings
1728
 * @param array $tools
1729
 *
1730
 * @return array
1731
 */
1732
function bigbluebuttonbn_get_recording_data($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1733
    $tabledata = array();
1734
    // Build table content.
1735
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
1736
        // There are recordings for this meeting.
1737
        foreach ($recordings as $recording) {
1738
            $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1739
            if (!empty($rowdata)) {
1740
                array_push($tabledata, $rowdata);
1741
            }
1742
        }
1743
    }
1744
    return $tabledata;
1745
}
1746
1747
/**
1748
 * Helper function builds the recording table.
1749
 *
1750
 * @param array $bbbsession
1751
 * @param array $recordings
1752
 * @param array $tools
1753
 *
1754
 * @return object
1755
 */
1756
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1757
    // Declare the table.
1758
    $table = new html_table();
1759
    $table->data = array();
1760
    // Initialize table headers.
1761
    $table->head[] = get_string('view_recording_playback', 'bigbluebuttonbn');
1762
    $table->head[] = get_string('view_recording_recording', 'bigbluebuttonbn');
1763
    $table->head[] = get_string('view_recording_description', 'bigbluebuttonbn');
1764
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1765
        $table->head[] = get_string('view_recording_preview', 'bigbluebuttonbn');
1766
    }
1767
    $table->head[] = get_string('view_recording_date', 'bigbluebuttonbn');
1768
    $table->head[] = get_string('view_recording_duration', 'bigbluebuttonbn');
1769
    $table->align = array('left', 'left', 'left', 'left', 'left', 'center');
1770
    $table->size = array('', '', '', '', '', '');
1771
    if ($bbbsession['managerecordings']) {
1772
        $table->head[] = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1773
        $table->align[] = 'left';
1774
        $table->size[] = (count($tools) * 40) . 'px';
1775
    }
1776
    // Build table content.
1777
    foreach ($recordings as $recording) {
1778
        $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1779
        if (!empty($rowdata)) {
1780
            $row = bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata);
1781
            array_push($table->data, $row);
1782
        }
1783
    }
1784
    return $table;
1785
}
1786
1787
/**
1788
 * Helper function builds the recording table row and insert into table.
1789
 *
1790
 * @param array $bbbsession
1791
 * @param array $recording
1792
 * @param object $rowdata
1793
 *
1794
 * @return object
1795
 */
1796
function bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $rowdata) {
1797
    $row = new html_table_row();
1798
    $row->id = 'recording-tr-'.$recording['recordID'];
1799
    $row->attributes['data-imported'] = 'false';
1800
    $texthead = '';
1801
    $texttail = '';
1802
    if (isset($recording['imported'])) {
1803
        $row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1804
        $row->attributes['data-imported'] = 'true';
1805
        $texthead = '<em>';
1806
        $texttail = '</em>';
1807
    }
1808
    $rowdata->date_formatted = str_replace(' ', '&nbsp;', $rowdata->date_formatted);
1809
    $row->cells = array();
1810
    $row->cells[] = $texthead . $rowdata->recording . $texttail;
1811
    $row->cells[] = $texthead . $rowdata->activity . $texttail;
1812
    $row->cells[] = $texthead . $rowdata->description . $texttail;
1813
    if (bigbluebuttonbn_get_recording_data_preview_enabled($bbbsession)) {
1814
        $row->cells[] = $rowdata->preview;
1815
    }
1816
    $row->cells[] = $texthead . $rowdata->date_formatted . $texttail;
1817
    $row->cells[] = $rowdata->duration_formatted;
1818
    if ($bbbsession['managerecordings']) {
1819
        $row->cells[] = $rowdata->actionbar;
1820
    }
1821
    return $row;
1822
}
1823
1824
/**
1825
 * Helper function evaluates if recording row should be included in the table.
1826
 *
1827
 * @param array $bbbsession
1828
 * @param array $recording
1829
 *
1830
 * @return boolean
1831
 */
1832
function bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) {
1833
    // Exclude unpublished recordings, only if user has no rights to manage them.
1834
    if ($recording['published'] != 'true' && !$bbbsession['managerecordings']) {
1835
        return false;
1836
    }
1837
    // Imported recordings are always shown as long as they are published.
1838
    if (isset($recording['imported'])) {
1839
        return true;
1840
    }
1841
    // When groups are enabled, exclude those to which the user doesn't have access to.
1842
    if (isset($bbbsession['group']) && $recording['meetingID'] != $bbbsession['meetingid']) {
1843
        return false;
1844
    }
1845
    return true;
1846
}
1847
1848
/**
1849
 * Helper function triggers a send notification when the recording is ready.
1850
 *
1851
 * @param object $bigbluebuttonbn
1852
 *
1853
 * @return void
1854
 */
1855
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) {
1856
    $sender = get_admin();
1857
    // Prepare message.
1858
    $messagetext = '<p>'.get_string('email_body_recording_ready_for', 'bigbluebuttonbn').
1859
        ' &quot;' . $bigbluebuttonbn->name . '&quot; '.
1860
        get_string('email_body_recording_ready_is_ready', 'bigbluebuttonbn').'.</p>';
1861
    $context = context_course::instance($bigbluebuttonbn->course);
1862
    \mod_bigbluebuttonbn\locallib\notifier::notification_send($context, $sender, $bigbluebuttonbn, $messagetext);
1863
}
1864
1865
/**
1866
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
1867
 *
1868
 * @return boolean
1869
 */
1870
function bigbluebuttonbn_is_bn_server() {
1871
    $parsedurl = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'));
1872
    if (!isset($parsedurl['host'])) {
1873
        return false;
1874
    }
1875
    $h = $parsedurl['host'];
1876
    $hends = explode('.', $h);
1877
    $hendslength = count($hends);
1878
    return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
1879
}
1880
1881
/**
1882
 * Helper function returns a list of courses a user has access to, wrapped in an array that can be used
1883
 * by a html select.
1884
 *
1885
 * @param array $bbbsession
1886
 *
1887
 * @return array
1888
 */
1889
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) {
1890
    if ($bbbsession['administrator']) {
1891
        $courses = get_courses('all', 'c.fullname ASC', 'c.id,c.shortname,c.fullname');
1892
        // It includes the name of the site as a course (category 0), so remove the first one.
1893
        unset($courses['1']);
1894
    } else {
1895
        $courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname');
1896
    }
1897
    $coursesforselect = [];
1898
    foreach ($courses as $course) {
1899
        $coursesforselect[$course->id] = $course->fullname;
1900
    }
1901
    return $coursesforselect;
1902
}
1903
1904
/**
1905
 * Helper function renders recording table.
1906
 *
1907
 * @param array $bbbsession
1908
 * @param array $recordings
1909
 * @param array $tools
1910
 *
1911
 * @return array
1912
 */
1913
function bigbluebuttonbn_output_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1914
    if (isset($recordings) && !empty($recordings)) {
1915
        // There are recordings for this meeting.
1916
        $table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools);
1917
    }
1918
    if (!isset($table) || !isset($table->data)) {
1919
        // Render a table with "No recordings".
1920
        return html_writer::div(get_string('view_message_norecordings', 'bigbluebuttonbn'), '',
1921
            array('id' => 'bigbluebuttonbn_recordings_table'));
1922
    }
1923
    // Render the table.
1924
    return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_recordings_table'));
1925
}
1926
1927
/**
1928
 * Helper function to convert an html string to plain text.
1929
 *
1930
 * @param string $html
1931
 * @param integer $len
1932
 *
1933
 * @return string
1934
 */
1935
function bigbluebuttonbn_html2text($html, $len = 0) {
1936
    $text = strip_tags($html);
1937
    $text = str_replace('&nbsp;', ' ', $text);
1938
    $textlen = strlen($text);
1939
    $text = substr($text, 0, $len);
1940
    if ($textlen > $len) {
1941
        $text .= '...';
1942
    }
1943
    return $text;
1944
}
1945
1946
/**
1947
 * Helper function to obtain the tags linked to a bigbluebuttonbn activity
1948
 *
1949
 * @param string $id
1950
 *
1951
 * @return string containing the tags separated by commas
1952
 */
1953
function bigbluebuttonbn_get_tags($id) {
1954
    if (class_exists('core_tag_tag')) {
1955
        return implode(',', core_tag_tag::get_item_tags_array('core', 'course_modules', $id));
1956
    }
1957
    return implode(',', tag_get_tags('bigbluebuttonbn', $id));
1958
}
1959
1960
/**
1961
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1962
 * in the getRecordings request
1963
 *
1964
 * @param string $courseid
1965
 * @param string $bigbluebuttonbnid
1966
 * @param bool   $subset
1967
 *
1968
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1969
 */
1970
function bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid = null, $subset = true) {
1971
    if (empty($courseid)) {
1972
        $courseid = 0;
1973
    }
1974
    if (empty($bigbluebuttonbnid)) {
1975
        return "course = '{$courseid}'";
1976
    }
1977
    if ($subset) {
1978
        return "id = '{$bigbluebuttonbnid}'";
1979
    }
1980
    return "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'";
1981
}
1982
1983
/**
1984
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1985
 * in the getRecordings request considering only those that belong to deleted activities.
1986
 *
1987
 * @param string $courseid
1988
 * @param string $bigbluebuttonbnid
1989
 * @param bool   $subset
1990
 *
1991
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1992
 */
1993 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...
1994
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_DELETE . "' AND meta like '%has_recordings%' AND meta like '%true%'";
1995
    if (empty($courseid)) {
1996
        $courseid = 0;
1997
    }
1998
    if (empty($bigbluebuttonbnid)) {
1999
        return $sql . " AND courseid = {$courseid}";
2000
    }
2001
    if ($subset) {
2002
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
2003
    }
2004
    return $sql . " AND courseid = {$courseid} AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
2005
}
2006
2007
/**
2008
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
2009
 * in the getRecordings request considering only those that belong to imported recordings.
2010
 *
2011
 * @param string $courseid
2012
 * @param string $bigbluebuttonbnid
2013
 * @param bool   $subset
2014
 *
2015
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
2016
 */
2017 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...
2018
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_IMPORT . "'";
2019
    if (empty($courseid)) {
2020
        $courseid = 0;
2021
    }
2022
    if (empty($bigbluebuttonbnid)) {
2023
        return $sql . " AND courseid = '{$courseid}'";
2024
    }
2025
    if ($subset) {
2026
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
2027
    }
2028
    return $sql . " AND courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
2029
}
2030
2031
/**
2032
 * Helper function to get recordings  and imported recordings together.
2033
 *
2034
 * @param string $courseid
2035
 * @param string $bigbluebuttonbnid
2036
 * @param bool   $subset
2037
 * @param bool   $includedeleted
2038
 *
2039
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2040
 * non sequential associative array itself that corresponds to the actual recording in BBB
2041
 */
2042
function bigbluebuttonbn_get_allrecordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
2043
    $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $subset, $includedeleted);
2044
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset);
2045
    return ($recordings + $recordingsimported);
2046
}
2047
2048
/**
2049
 * Helper function to retrieve recordings from the BigBlueButton. The references are stored as events
2050
 * in bigbluebuttonbn_logs.
2051
 *
2052
 * @param string $courseid
2053
 * @param string $bigbluebuttonbnid
2054
 * @param bool   $subset
2055
 * @param bool   $includedeleted
2056
 *
2057
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2058
 * non sequential associative array itself that corresponds to the actual recording in BBB
2059
 */
2060
function bigbluebuttonbn_get_recordings($courseid = 0, $bigbluebuttonbnid = null, $subset = true, $includedeleted = false) {
2061
    global $DB;
2062
    $select = bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid, $subset);
2063
    $bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid');
2064
    /* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in
2065
     * the getRecordings request. */
2066
    if ($includedeleted) {
2067
        $selectdeleted = bigbluebuttonbn_get_recordings_deleted_sql_select($courseid, $bigbluebuttonbnid, $subset);
2068
        $bigbluebuttonbnsdel = $DB->get_records_select_menu('bigbluebuttonbn_logs', $selectdeleted, null,
2069
            'bigbluebuttonbnid', 'bigbluebuttonbnid, meetingid');
2070
        if (!empty($bigbluebuttonbnsdel)) {
2071
            // Merge bigbluebuttonbnis from deleted instances, only keys are relevant.
2072
            // Artimetic merge is used in order to keep the keys.
2073
            $bigbluebuttonbns += $bigbluebuttonbnsdel;
2074
        }
2075
    }
2076
    // Gather the meetingids from bigbluebuttonbn logs that include a create with record=true.
2077
    if (empty($bigbluebuttonbns)) {
2078
        return array();
2079
    }
2080
    // Prepare select for loading records based on existent bigbluebuttonbns.
2081
    $sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE ';
2082
    $sql .= '(bigbluebuttonbnid='.implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)).')';
2083
    // Include only Create events and exclude those with record not true.
2084
    $sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?';
2085
    // Execute select for loading records based on existent bigbluebuttonbns.
2086
    $records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%'));
2087
    // Get actual recordings.
2088
    return bigbluebuttonbn_get_recordings_array(array_keys($records));
2089
}
2090
2091
/**
2092
 * Helper function iterates an array with recordings and unset those already imported.
2093
 *
2094
 * @param array $recordings
2095
 * @param integer $courseid
2096
 * @param integer $bigbluebuttonbnid
2097
 *
2098
 * @return array
2099
 */
2100
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) {
2101
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true);
2102
    foreach ($recordings as $key => $recording) {
2103
        if (isset($recordingsimported[$recording['recordID']])) {
2104
            unset($recordings[$key]);
2105
        }
2106
    }
2107
    return $recordings;
2108
}
2109
2110
/**
2111
 * Helper function to count the imported recordings for a recordingid.
2112
 *
2113
 * @param string $recordid
2114
 *
2115
 * @return integer
2116
 */
2117
function bigbluebuttonbn_count_recording_imported_instances($recordid) {
2118
    global $DB;
2119
    $sql = 'SELECT COUNT(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2120
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%"));
2121
}
2122
2123
/**
2124
 * Helper function returns an array with all the instances of imported recordings for a recordingid.
2125
 *
2126
 * @param string $recordid
2127
 *
2128
 * @return array
2129
 */
2130
function bigbluebuttonbn_get_recording_imported_instances($recordid) {
2131
    global $DB;
2132
    $sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2133
    $recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%',
2134
        "%{$recordid}%"));
2135
    return $recordingsimported;
2136
}
2137
2138
/**
2139
 * Helper function returns an array with the profiles (with features per profile) for the different types
2140
 * of bigbluebuttonbn instances.
2141
 *
2142
 * @return array
2143
 */
2144
function bigbluebuttonbn_get_instance_type_profiles() {
2145
    $instanceprofiles = array(
2146
            array('id' => BIGBLUEBUTTONBN_TYPE_ALL, 'name' => get_string('instance_type_default', 'bigbluebuttonbn'),
2147
                'features' => array('all')),
2148
            array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY, 'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'),
2149
                'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit', 'recording',
2150
                    'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups',
2151
                    'modstandardelshdr', 'availabilityconditionsheader', 'tagshdr', 'competenciessection')),
2152
            array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY, 'name' => get_string('instance_type_recording_only',
2153
                'bigbluebuttonbn'), 'features' => array('showrecordings', 'importrecordings')),
2154
    );
2155
    return $instanceprofiles;
2156
}
2157
2158
/**
2159
 * Helper function returns an array with enabled features for an specific profile type.
2160
 *
2161
 * @param array $typeprofiles
2162
 * @param string $type
2163
 *
2164
 * @return array
2165
 */
2166
function bigbluebuttonbn_get_enabled_features($typeprofiles, $type = null) {
2167
    $enabledfeatures = array();
2168
    $features = $typeprofiles[0]['features'];
2169
    if (!is_null($type)) {
2170
        $features = $typeprofiles[$type]['features'];
2171
    }
2172
    $enabledfeatures['showroom'] = (in_array('all', $features) || in_array('showroom', $features));
2173
    // Evaluates if recordings are enabled for the Moodle site.
2174
    $enabledfeatures['showrecordings'] = false;
2175
    if (\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
2176
        $enabledfeatures['showrecordings'] = (in_array('all', $features) || in_array('showrecordings', $features));
2177
    }
2178
    $enabledfeatures['importrecordings'] = false;
2179
    if (\mod_bigbluebuttonbn\locallib\config::importrecordings_enabled()) {
2180
        $enabledfeatures['importrecordings'] = (in_array('all', $features) || in_array('importrecordings', $features));
2181
    }
2182
    return $enabledfeatures;
2183
}
2184
2185
/**
2186
 * Helper function returns an array with the profiles (with features per profile) for the different types
2187
 * of bigbluebuttonbn instances.
2188
 *
2189
 * @param array $profiles
2190
 *
2191
 * @return array
2192
 */
2193
function bigbluebuttonbn_get_instance_profiles_array($profiles = null) {
2194
    if (is_null($profiles) || empty($profiles)) {
2195
        $profiles = bigbluebuttonbn_get_instance_type_profiles();
2196
    }
2197
    $profilesarray = array();
2198
    foreach ($profiles as $profile) {
2199
        $profilesarray += array("{$profile['id']}" => $profile['name']);
2200
    }
2201
    return $profilesarray;
2202
}
2203
2204
/**
2205
 * Helper function returns time in a formatted string.
2206
 *
2207
 * @param integer $time
2208
 *
2209
 * @return string
2210
 */
2211
function bigbluebuttonbn_format_activity_time($time) {
2212
    $activitytime = '';
2213
    if ($time) {
2214
        $activitytime = calendar_day_representation($time).' '.
2215
          get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn').' '.
2216
          calendar_time_representation($time);
2217
    }
2218
    return $activitytime;
2219
}
2220
2221
/**
2222
 * Helper function returns array with all the strings to be used in javascript.
2223
 *
2224
 * @return array
2225
 */
2226
function bigbluebuttonbn_get_strings_for_js() {
2227
    $locale = bigbluebuttonbn_get_locale();
2228
    $stringman = get_string_manager();
2229
    $strings = $stringman->load_component_strings('bigbluebuttonbn', $locale);
2230
    return $strings;
2231
}
2232
2233
/**
2234
 * Helper function returns the locale set by moodle.
2235
 *
2236
 * @return string
2237
 */
2238
function bigbluebuttonbn_get_locale() {
2239
    $lang = get_string('locale', 'core_langconfig');
2240
    return substr($lang, 0, strpos($lang, '.'));
2241
}
2242
2243
/**
2244
 * Helper function returns the locale code based on the locale set by moodle.
2245
 *
2246
 * @return string
2247
 */
2248
function bigbluebuttonbn_get_localcode() {
2249
    $locale = bigbluebuttonbn_get_locale();
2250
    return substr($locale, 0, strpos($locale, '_'));
2251
}
2252
2253
/**
2254
 * Helper function returns array with the instance settings used in views.
2255
 *
2256
 * @param string $id
2257
 * @param object $bigbluebuttonbnid
2258
 *
2259
 * @return array
2260
 */
2261
function bigbluebuttonbn_view_validator($id, $bigbluebuttonbnid) {
2262
    if ($id) {
2263
        return bigbluebuttonbn_view_instance_id($id);
2264
    }
2265
    if ($bigbluebuttonbnid) {
2266
        return bigbluebuttonbn_view_instance_bigbluebuttonbn($bigbluebuttonbnid);
2267
    }
2268
    return;
2269
}
2270
2271
/**
2272
 * Helper function returns array with the instance settings used in views based on id.
2273
 *
2274
 * @param string $id
2275
 *
2276
 * @return array
2277
 */
2278 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...
2279
    global $DB;
2280
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2281
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2282
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2283
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2284
}
2285
2286
/**
2287
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2288
 *
2289
 * @param object $bigbluebuttonbnid
2290
 *
2291
 * @return array
2292
 */
2293 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...
2294
    global $DB;
2295
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2296
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2297
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2298
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2299
}
2300
2301
/**
2302
 * Helper function renders general warning message for settings (if any).
2303
 *
2304
 * @param object $renderer
2305
 *
2306
 * @return void
2307
 */
2308
function bigbluebuttonbn_settings_general_warning(&$renderer) {
0 ignored issues
show
Unused Code introduced by
The parameter $renderer is not used and could be removed.

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

Loading history...
2309
    return;
2310
}
2311
2312
/**
2313
 * Helper function renders general settings if the feature is enabled.
2314
 *
2315
 * @param object $renderer
2316
 *
2317
 * @return void
2318
 */
2319
function bigbluebuttonbn_settings_general(&$renderer) {
2320
    // Configuration for BigBlueButton.
2321
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_general_shown()) {
2322
        $renderer->render_group_header('general');
2323
        $renderer->render_group_element('server_url',
2324
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL));
2325
        $renderer->render_group_element('shared_secret',
2326
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET));
2327
    }
2328
}
2329
2330
/**
2331
 * Helper function renders record settings if the feature is enabled.
2332
 *
2333
 * @param object $renderer
2334
 *
2335
 * @return void
2336
 */
2337
function bigbluebuttonbn_settings_record(&$renderer) {
2338
    // Configuration for 'recording' feature.
2339 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_record_meeting_shown()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
2340
        $renderer->render_group_header('recording');
2341
        $renderer->render_group_element('recording_default',
2342
            $renderer->render_group_element_checkbox('recording_default', 1));
2343
        $renderer->render_group_element('recording_editable',
2344
            $renderer->render_group_element_checkbox('recording_editable', 1));
2345
        $renderer->render_group_element('recording_icons_enabled',
2346
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1));
2347
    }
2348
}
2349
2350
/**
2351
 * Helper function renders import recording settings if the feature is enabled.
2352
 *
2353
 * @param object $renderer
2354
 *
2355
 * @return void
2356
 */
2357 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...
2358
    // Configuration for 'import recordings' feature.
2359
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_import_recordings_shown()) {
2360
        $renderer->render_group_header('importrecordings');
2361
        $renderer->render_group_element('importrecordings_enabled',
2362
            $renderer->render_group_element_checkbox('importrecordings_enabled', 0));
2363
        $renderer->render_group_element('importrecordings_from_deleted_enabled',
2364
            $renderer->render_group_element_checkbox('importrecordings_from_deleted_enabled', 0));
2365
    }
2366
}
2367
2368
/**
2369
 * Helper function renders show recording settings if the feature is enabled.
2370
 *
2371
 * @param object $renderer
2372
 *
2373
 * @return void
2374
 */
2375
function bigbluebuttonbn_settings_showrecordings(&$renderer) {
2376
    // Configuration for 'show recordings' feature.
2377
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_show_recordings_shown()) {
2378
        $renderer->render_group_header('recordings');
2379
        $renderer->render_group_element('recordings_html_default',
2380
            $renderer->render_group_element_checkbox('recordings_html_default', 1));
2381
        $renderer->render_group_element('recordings_html_editable',
2382
            $renderer->render_group_element_checkbox('recordings_html_editable', 0));
2383
        $renderer->render_group_element('recordings_deleted_default',
2384
            $renderer->render_group_element_checkbox('recordings_deleted_default', 1));
2385
        $renderer->render_group_element('recordings_deleted_editable',
2386
            $renderer->render_group_element_checkbox('recordings_deleted_editable', 0));
2387
        $renderer->render_group_element('recordings_imported_default',
2388
            $renderer->render_group_element_checkbox('recordings_imported_default', 0));
2389
        $renderer->render_group_element('recordings_imported_editable',
2390
            $renderer->render_group_element_checkbox('recordings_imported_editable', 1));
2391
        $renderer->render_group_element('recordings_preview_default',
2392
            $renderer->render_group_element_checkbox('recordings_preview_default', 1));
2393
        $renderer->render_group_element('recordings_preview_editable',
2394
            $renderer->render_group_element_checkbox('recordings_preview_editable', 0));
2395
    }
2396
}
2397
2398
/**
2399
 * Helper function renders wait for moderator settings if the feature is enabled.
2400
 *
2401
 * @param object $renderer
2402
 *
2403
 * @return void
2404
 */
2405
function bigbluebuttonbn_settings_waitmoderator(&$renderer) {
2406
    // Configuration for wait for moderator feature.
2407
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_wait_moderator_shown()) {
2408
        $renderer->render_group_header('waitformoderator');
2409
        $renderer->render_group_element('waitformoderator_default',
2410
            $renderer->render_group_element_checkbox('waitformoderator_default', 0));
2411
        $renderer->render_group_element('waitformoderator_editable',
2412
            $renderer->render_group_element_checkbox('waitformoderator_editable', 1));
2413
        $renderer->render_group_element('waitformoderator_ping_interval',
2414
            $renderer->render_group_element_text('waitformoderator_ping_interval', 10, PARAM_INT));
2415
        $renderer->render_group_element('waitformoderator_cache_ttl',
2416
            $renderer->render_group_element_text('waitformoderator_cache_ttl', 60, PARAM_INT));
2417
    }
2418
}
2419
2420
/**
2421
 * Helper function renders static voice bridge settings if the feature is enabled.
2422
 *
2423
 * @param object $renderer
2424
 *
2425
 * @return void
2426
 */
2427
function bigbluebuttonbn_settings_voicebridge(&$renderer) {
2428
    // Configuration for "static voice bridge" feature.
2429
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_static_voice_bridge_shown()) {
2430
        $renderer->render_group_header('voicebridge');
2431
        $renderer->render_group_element('voicebridge_editable',
2432
            $renderer->render_group_element_checkbox('voicebridge_editable', 0));
2433
    }
2434
}
2435
2436
/**
2437
 * Helper function renders preuploaded presentation settings if the feature is enabled.
2438
 *
2439
 * @param object $renderer
2440
 *
2441
 * @return void
2442
 */
2443
function bigbluebuttonbn_settings_preupload(&$renderer) {
2444
    // Configuration for "preupload presentation" feature.
2445
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_preupload_presentation_shown()) {
2446
        // This feature only works if curl is installed.
2447
        $preuploaddescripion = get_string('config_preuploadpresentation_description', 'bigbluebuttonbn');
2448
        if (!extension_loaded('curl')) {
2449
            $preuploaddescripion .= '<div class="form-defaultinfo">';
2450
            $preuploaddescripion .= get_string('config_warning_curl_not_installed', 'bigbluebuttonbn');
2451
            $preuploaddescripion .= '</div><br>';
2452
        }
2453
        $renderer->render_group_header('preuploadpresentation', null, $preuploaddescripion);
2454
        if (extension_loaded('curl')) {
2455
            $renderer->render_group_element('preuploadpresentation_enabled',
2456
                $renderer->render_group_element_checkbox('preuploadpresentation_enabled', 0));
2457
        }
2458
    }
2459
}
2460
2461
/**
2462
 * Helper function renders userlimit settings if the feature is enabled.
2463
 *
2464
 * @param object $renderer
2465
 *
2466
 * @return void
2467
 */
2468
function bigbluebuttonbn_settings_userlimit(&$renderer) {
2469
    // Configuration for "user limit" feature.
2470
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_user_limit_shown()) {
2471
        $renderer->render_group_header('userlimit');
2472
        $renderer->render_group_element('userlimit_default',
2473
            $renderer->render_group_element_text('userlimit_default', 0, PARAM_INT));
2474
        $renderer->render_group_element('userlimit_editable',
2475
            $renderer->render_group_element_checkbox('userlimit_editable', 0));
2476
    }
2477
}
2478
2479
/**
2480
 * Helper function renders duration settings if the feature is enabled.
2481
 *
2482
 * @param object $renderer
2483
 *
2484
 * @return void
2485
 */
2486
function bigbluebuttonbn_settings_duration(&$renderer) {
2487
    // Configuration for "scheduled duration" feature.
2488 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_scheduled_duration_shown()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
2489
        $renderer->render_group_header('scheduled');
2490
        $renderer->render_group_element('scheduled_duration_enabled',
2491
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1));
2492
        $renderer->render_group_element('scheduled_duration_compensation',
2493
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT));
2494
        $renderer->render_group_element('scheduled_pre_opening',
2495
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT));
2496
    }
2497
}
2498
2499
/**
2500
 * Helper function renders participant settings if the feature is enabled.
2501
 *
2502
 * @param object $renderer
2503
 *
2504
 * @return void
2505
 */
2506
function bigbluebuttonbn_settings_participants(&$renderer) {
2507
    // Configuration for defining the default role/user that will be moderator on new activities.
2508
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_moderator_default_shown()) {
2509
        $renderer->render_group_header('participant');
2510
        // UI for 'participants' feature.
2511
        $roles = bigbluebuttonbn_get_roles();
2512
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2513
        $renderer->render_group_element('participant_moderator_default',
2514
            $renderer->render_group_element_configmultiselect('participant_moderator_default',
2515
                array_keys($owner), array_merge($owner, $roles))
2516
          );
2517
    }
2518
}
2519
2520
/**
2521
 * Helper function renders notification settings if the feature is enabled.
2522
 *
2523
 * @param object $renderer
2524
 *
2525
 * @return void
2526
 */
2527
function bigbluebuttonbn_settings_notifications(&$renderer) {
2528
    // Configuration for "send notifications" feature.
2529
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_send_notifications_shown()) {
2530
        $renderer->render_group_header('sendnotifications');
2531
        $renderer->render_group_element('sendnotifications_enabled',
2532
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1));
2533
    }
2534
}
2535
2536
/**
2537
 * Helper function renders extended settings if any of the features there is enabled.
2538
 *
2539
 * @param object $renderer
2540
 *
2541
 * @return void
2542
 */
2543 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...
2544
    // Configuration for extended BN capabilities.
2545
    if (!bigbluebuttonbn_is_bn_server()) {
2546
        return;
2547
    }
2548
    // Configuration for 'notify users when recording ready' feature.
2549
    if ((boolean)\mod_bigbluebuttonbn\settings\validator::section_settings_extended_shown()) {
2550
        $renderer->render_group_header('extended_capabilities');
2551
        // UI for 'notify users when recording ready' feature.
2552
        $renderer->render_group_element('recordingready_enabled',
2553
            $renderer->render_group_element_checkbox('recordingready_enabled', 0));
2554
        // UI for 'register meeting events' feature.
2555
        $renderer->render_group_element('meetingevents_enabled',
2556
            $renderer->render_group_element_checkbox('meetingevents_enabled', 0));
2557
    }
2558
}
2559
2560
/**
2561
 * Helper function returns an encoded meetingid.
2562
 *
2563
 * @param string $seed
2564
 *
2565
 * @return string
2566
 */
2567
function bigbluebuttonbn_encode_meetingid($seed) {
2568
    global $CFG;
2569
    return sha1($CFG->wwwroot . $seed . \mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
2570
}
2571
2572
/**
2573
 * Helper function renders the link used for recording type in row for the data used by the recording table.
2574
 *
2575
 * @param array $recording
2576
 * @param array $bbbsession
2577
 * @param array $playback
2578
 *
2579
 * @return boolean
2580
 */
2581
function bigbluebuttonbn_include_recording_data_row_type($recording, $bbbsession, $playback) {
2582
    // All types that are not restricted are included.
2583
    if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'false') {
2584
        return true;
2585
    }
2586
    // All types that are not statistics are included.
2587
    if ($playback['type'] != 'statistics') {
2588
        return true;
2589
    }
2590
    // Exclude imported recordings.
2591
    if (isset($recording['imported'])) {
2592
        return false;
2593
    }
2594
    // Exclude non moderators.
2595
    if (!$bbbsession['administrator'] && !$bbbsession['moderator']) {
2596
        return false;
2597
    }
2598
    return true;
2599
}
2600
2601
/**
2602
 * Renders the general warning message.
2603
 *
2604
 * @param string $message
2605
 * @param string $type
2606
 * @param string $href
2607
 * @param string $text
2608
 * @param string $class
2609
 *
2610
 * @return string
2611
 */
2612
function bigbluebuttonbn_render_warning($message, $type='info', $href='', $text='', $class='') {
2613
    global $OUTPUT;
2614
    $output = "\n";
2615
    // Evaluates if config_warning is enabled.
2616
    if (empty($message)) {
2617
        return $output;
2618
    }
2619
    $output .= $OUTPUT->box_start('box boxalignleft adminerror alert alert-' . $type . ' alert-block fade in',
2620
      'bigbluebuttonbn_view_general_warning') . "\n";
2621
    $output .= '    ' . $message . "\n";
2622
    $output .= '  <div class="singlebutton pull-right">' . "\n";
2623
    if (!empty($href)) {
2624
        $output .= bigbluebuttonbn_render_warning_button($href, $text, $class);
2625
    }
2626
    $output .= '  </div>' . "\n";
2627
    $output .= $OUTPUT->box_end() . "\n";
2628
    return $output;
2629
}
2630
2631
/**
2632
 * Renders the general warning button.
2633
 *
2634
 * @param string $href
2635
 * @param string $text
2636
 * @param string $class
2637
 * @param string $title
2638
 *
2639
 * @return string
2640
 */
2641
function bigbluebuttonbn_render_warning_button($href, $text = '', $class = '', $title = '') {
2642
    if ($text == '') {
2643
        $text = get_string('ok', 'moodle');
2644
    }
2645
    if ($title == '') {
2646
        $title = $text;
2647
    }
2648
    if ($class == '') {
2649
        $class = 'btn btn-secondary';
2650
    }
2651
    $output  = '  <form method="post" action="' . $href . '" class="form-inline">'."\n";
2652
    $output .= '      <button type="submit" class="' . $class . '"'."\n";
2653
    $output .= '          title="' . $title . '"'."\n";
2654
    $output .= '          >' . $text . '</button>'."\n";
2655
    $output .= '  </form>'."\n";
2656
    return $output;
2657
}
2658
2659
/**
2660
 * Check if a BigBlueButtonBN is available to be used by the current user.
2661
 *
2662
 * @param  stdClass  $bigbluebuttonbn  BigBlueButtonBN instance
2663
 *
2664
 * @return boolean                     status if room available and current user allowed to join
2665
 */
2666
function bigbluebuttonbn_get_availability_status($bigbluebuttonbn) {
2667
    list($roomavailable) = bigbluebuttonbn_room_is_available($bigbluebuttonbn);
2668
    list($usercanjoin) = bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn);
2669
2670
    return ($roomavailable && $usercanjoin);
2671
}
2672
2673
/**
2674
 * Helper for evaluating if scheduled activity is avaiable.
2675
 *
2676
 * @param  stdClass  $bigbluebuttonbn  BigBlueButtonBN instance
2677
 *
2678
 * @return array                       status (room available or not and possible warnings)
2679
 */
2680
function bigbluebuttonbn_room_is_available($bigbluebuttonbn) {
2681
    $open = true;
2682
    $closed = false;
2683
    $warnings = array();
2684
2685
    $timenow = time();
2686
    $timeopen = $bigbluebuttonbn->openingtime;
2687
    $timeclose = $bigbluebuttonbn->closingtime;
2688
    if (!empty($timeopen) && $timeopen > $timenow) {
2689
        $open = false;
2690
    }
2691
    if (!empty($timeclose) && $timenow > $timeclose) {
2692
        $closed = true;
2693
    }
2694
2695
    if (!$open || $closed) {
2696
        if (!$open) {
2697
            $warnings['notopenyet'] = userdate($timeopen);
2698
        }
2699
        if ($closed) {
2700
            $warnings['expired'] = userdate($timeclose);
2701
        }
2702
        return array(false, $warnings);
2703
    }
2704
2705
    return array(true, $warnings);
2706
}
2707
2708
/**
2709
 * Helper for evaluating if meeting can be joined.
2710
 *
2711
 * @param  stdClass $bigbluebuttonbn  BigBlueButtonBN instance
2712
 * @param  string   $mid
2713
 * @param  integer  $userid
2714
 *
2715
 * @return array    status (user allowed to join or not and possible message)
2716
 */
2717
function bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn, $mid = null, $userid = null) {
2718
2719
    // By default, use a meetingid without groups.
2720
    if (empty($mid)) {
2721
        $mid = $bigbluebuttonbn->meetingid . '-' . $bigbluebuttonbn->course . '-' . $bigbluebuttonbn->id;
2722
    }
2723
2724
    // When meeting is running, all authorized users can join right in.
2725
    if (bigbluebuttonbn_is_meeting_running($mid)) {
2726
        return array(true, get_string('view_message_conference_in_progress', 'bigbluebuttonbn'));
2727
    }
2728
2729
    // When meeting is not running, see if the user can join.
2730
    $context = context_course::instance($bigbluebuttonbn->course);
2731
    $participantlist = bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context);
2732
    $isadmin = is_siteadmin($userid);
2733
    $ismoderator = bigbluebuttonbn_is_moderator($context, $participantlist, $userid);
2734
    // If user is administrator, moderator or if is viewer and no waiting is required, join allowed.
2735
    if ($isadmin || $ismoderator || !$bigbluebuttonbn->wait) {
2736
        return array(true, get_string('view_message_conference_room_ready', 'bigbluebuttonbn'));
2737
    }
2738
    // Otherwise, no join allowed.
2739
    return array(false, get_string('view_message_conference_wait_for_moderator', 'bigbluebuttonbn'));
2740
}
2741
2742
/**
2743
 * Helper for getting a value from a bigbluebuttonbn cache.
2744
 *
2745
 * @param  string   $name       BigBlueButtonBN cache
2746
 * @param  string   $key        Key to be retrieved
2747
 * @param  integer  $default    Default value in case key is not found or it is empty
2748
 *
2749
 * @return variable key value
2750
 */
2751
function bigbluebuttonbn_cache_get($name, $key, $default = null) {
2752
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', $name);
2753
    $result = $cache->get($key);
2754
    if (!empty($result)) {
2755
        return $result;
2756
    }
2757
    return $default;
2758
}
2759
2760
/**
2761
 * Helper for setting a value in a bigbluebuttonbn cache.
2762
 *
2763
 * @param  string   $name       BigBlueButtonBN cache
2764
 * @param  string   $key        Key to be created/updated
2765
 * @param  variable $value      Default value to be set
2766
 */
2767
function bigbluebuttonbn_cache_set($name, $key, $value) {
2768
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', $name);
2769
    $result = $cache->set($key, $value);
0 ignored issues
show
Unused Code introduced by
$result 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...
2770
}
2771
2772
/**
2773
 * Helper for getting the owner userid of a bigbluebuttonbn instance.
2774
 *
2775
 * @param  stdClass $bigbluebuttonbn  BigBlueButtonBN instance
2776
 *
2777
 * @return integer ownerid (a valid user id or null if not registered/found)
2778
 */
2779
function bigbluebuttonbn_instance_ownerid($bigbluebuttonbn) {
2780
    global $DB;
2781
    $filters = array('bigbluebuttonbnid' => $bigbluebuttonbn->id, 'log' => 'Add');
2782
    $ownerid = (integer)$DB->get_field('bigbluebuttonbn_logs', 'userid', $filters);
2783
    return $ownerid;
2784
}
2785