Completed
Pull Request — master (#45)
by Jesus
02:22
created

locallib.php ➔ bigbluebutonbn_settings_general_warning()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

Loading history...
232
}
233
234
/**
235
 * Helper function to fetch recordings from a BigBlueButton server.
236
 *
237
 * @param array $meetingidsarray   array with meeting ids in the form array("mid1","mid2","mid3")
238
 *
239
 * @return associative array with recordings indexed by recordID, each recording is a non sequential associative array
240
 */
241
function bigbluebuttonbn_get_recordings_array_fetch($meetingidsarray) {
242
    $recordings = array();
243
    // Execute a paginated getRecordings request.
244
    $pages = floor(count($meetingidsarray) / 25) + 1;
245
    for ($page = 1; $page <= $pages; ++$page) {
246
        $mids = array_slice($meetingidsarray, ($page - 1) * 25, 25);
247
        $recordings += bigbluebuttonbn_get_recordings_array_fetch_page($mids);
248
    }
249
    return $recordings;
250
}
251
252
/**
253
 * Helper function to fetch one page of upto 25 recordings from a BigBlueButton server.
254
 *
255
 * @param array  $mids
256
 *
257
 * @return array
258
 */
259
function bigbluebuttonbn_get_recordings_array_fetch_page($mids) {
260
    $recordings = array();
261
    // Do getRecordings is executed using a method GET (supported by all versions of BBB).
262
    $url = \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getRecordings', ['meetingID' => implode(',', $mids)]);
263
    $xml = bigbluebuttonbn_wrap_xml_load_file($url);
264
    if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
265
        // If there were meetings already created.
266
        foreach ($xml->recordings->recording as $recordingxml) {
267
            $recording = bigbluebuttonbn_get_recording_array_value($recordingxml);
268
            $recordings[$recording['recordID']] = $recording;
269
        }
270
    }
271
    return $recordings;
272
}
273
274
/**
275
 * Helper function to remove a set of recordings from an array.
276
 *
277
 * @param array  $rids
278
 * @param array  $recordings
279
 *
280
 * @return array
281
 */
282
function bigbluebuttonbn_get_recordings_array_filter($rids, &$recordings) {
283
    foreach ($recordings as $key => $recording) {
284
        if (!in_array($recording['recordID'], $rids)) {
285
            unset($recordings[$key]);
286
        }
287
    }
288
    return $recordings;
289
}
290
291
/**
292
 * Helper function to retrieve imported recordings from the Moodle database.
293
 * The references are stored as events in bigbluebuttonbn_logs.
294
 *
295
 * @param string $courseid
296
 * @param string $bigbluebuttonbnid
297
 * @param bool   $subset
298
 *
299
 * @return associative array with imported recordings indexed by recordID, each recording
300
 * is a non sequential associative array that corresponds to the actual recording in BBB
301
 */
302
function bigbluebuttonbn_get_recordings_imported_array($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
303
    global $DB;
304
    $select = bigbluebuttonbn_get_recordings_imported_sql_select($courseid, $bigbluebuttonbnid, $subset);
305
    $recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select);
306
    $recordsimportedarray = array();
307
    foreach ($recordsimported as $recordimported) {
308
        $meta = json_decode($recordimported->meta, true);
309
        $recording = $meta['recording'];
310
        // Override imported flag with actual ID.
311
        $recording['imported'] = $recordimported->id;
312
        if (isset($recordimported->protected)) {
313
            $recording['protected'] = (string) $recordimported->protected;
314
        }
315
        $recordsimportedarray[$recording['recordID']] = $recording;
316
    }
317
    return $recordsimportedarray;
318
}
319
320
/**
321
 * Helper function to retrive the default config.xml file.
322
 *
323
 * @return string
324
 */
325
function bigbluebuttonbn_get_default_config_xml() {
326
    $xml = bigbluebuttonbn_wrap_xml_load_file(
327
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getDefaultConfigXML')
328
      );
329
    return $xml;
330
}
331
332
/**
333
 * Helper function to convert an xml recording object to an array in the format used by the plugin.
334
 *
335
 * @param object $recording
336
 *
337
 * @return array
338
 */
339
function bigbluebuttonbn_get_recording_array_value($recording) {
340
    // Add formats.
341
    $playbackarray = array();
342
    foreach ($recording->playback->format as $format) {
343
        $playbackarray[(string) $format->type] = array('type' => (string) $format->type,
344
            'url' => trim((string) $format->url), 'length' => (string) $format->length);
345
        // Add preview per format when existing.
346
        if ($format->preview) {
347
            $playbackarray[(string) $format->type]['preview'] = bigbluebuttonbn_get_recording_preview_images($format->preview);
348
        }
349
    }
350
    // Add the metadata to the recordings array.
351
    $metadataarray = bigbluebuttonbn_get_recording_array_meta(get_object_vars($recording->metadata));
0 ignored issues
show
Documentation introduced by
get_object_vars($recording->metadata) is of type array, but the function expects a object.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

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

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

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

Loading history...
2281
    global $DB;
2282
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2283
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2284
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2285
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2286
}
2287
2288
/**
2289
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2290
 *
2291
 * @param object $bigbluebuttonbnid
2292
 *
2293
 * @return array
2294
 */
2295 View Code Duplication
function bigbluebuttonbn_views_instance_bigbluebuttonbn($bigbluebuttonbnid) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2296
    global $DB;
2297
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2298
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2299
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2300
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2301
}
2302
2303
/**
2304
 * Helper function renders general warning message for settings (if any).
2305
 *
2306
 * @param object $renderer
2307
 *
2308
 * @return void
2309
 */
2310
function bigbluebutonbn_settings_general_warning(&$renderer) {
2311
    global $BIGBLUEBUTTONBN_CFG;
2312
    if (isset($BIGBLUEBUTTONBN_CFG)) {
2313
        $msg = get_string('config_warning_bigbluebuttonbn_cfg_deprecated', 'bigbluebuttonbn');
2314
        $renderer->render_warning_message($msg);
2315
    }
2316
}
2317
2318
/**
2319
 * Helper function renders general settings if the feature is enabled.
2320
 *
2321
 * @param object $renderer
2322
 *
2323
 * @return void
2324
 */
2325
function bigbluebutonbn_settings_general(&$renderer) {
2326
    // Configuration for BigBlueButton.
2327
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_general_shown()) {
2328
        $renderer->render_group_header('general');
2329
        $renderer->render_group_element('server_url',
2330
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL));
2331
        $renderer->render_group_element('shared_secret',
2332
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET));
2333
    }
2334
}
2335
2336
/**
2337
 * Helper function renders record settings if the feature is enabled.
2338
 *
2339
 * @param object $renderer
2340
 *
2341
 * @return void
2342
 */
2343
function bigbluebutonbn_settings_record(&$renderer) {
2344
    // Configuration for 'recording' feature.
2345 View Code Duplication
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_record_meeting_shown()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
2346
        $renderer->render_group_header('recording');
2347
        $renderer->render_group_element('recording_default',
2348
            $renderer->render_group_element_checkbox('recording_default', 1));
2349
        $renderer->render_group_element('recording_editable',
2350
            $renderer->render_group_element_checkbox('recording_editable', 1));
2351
        $renderer->render_group_element('recording_icons_enabled',
2352
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1));
2353
    }
2354
}
2355
2356
/**
2357
 * Helper function renders import recording settings if the feature is enabled.
2358
 *
2359
 * @param object $renderer
2360
 *
2361
 * @return void
2362
 */
2363 View Code Duplication
function bigbluebutonbn_settings_importrecordings(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

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

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

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

Loading history...
2491
        $renderer->render_group_header('scheduled');
2492
        $renderer->render_group_element('scheduled_duration_enabled',
2493
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1));
2494
        $renderer->render_group_element('scheduled_duration_compensation',
2495
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT));
2496
        $renderer->render_group_element('scheduled_pre_opening',
2497
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT));
2498
    }
2499
}
2500
2501
/**
2502
 * Helper function renders participant settings if the feature is enabled.
2503
 *
2504
 * @param object $renderer
2505
 *
2506
 * @return void
2507
 */
2508
function bigbluebutonbn_settings_participants(&$renderer) {
2509
    // Configuration for defining the default role/user that will be moderator on new activities.
2510
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_moderator_default_shown()) {
2511
        $renderer->render_group_header('participant');
2512
        // UI for 'participants' feature.
2513
        $roles = bigbluebuttonbn_get_roles();
2514
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2515
        $renderer->render_group_element('participant_moderator_default',
2516
            $renderer->render_group_element_configmultiselect('participant_moderator_default',
2517
                array_keys($owner), array_merge($owner, $roles))
2518
          );
2519
    }
2520
}
2521
2522
/**
2523
 * Helper function renders notification settings if the feature is enabled.
2524
 *
2525
 * @param object $renderer
2526
 *
2527
 * @return void
2528
 */
2529
function bigbluebutonbn_settings_notifications(&$renderer) {
2530
    // Configuration for "send notifications" feature.
2531
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_send_notifications_shown()) {
2532
        $renderer->render_group_header('sendnotifications');
2533
        $renderer->render_group_element('sendnotifications_enabled',
2534
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1));
2535
    }
2536
}
2537
2538
/**
2539
 * Helper function renders extended settings if any of the features there is enabled.
2540
 *
2541
 * @param object $renderer
2542
 *
2543
 * @return void
2544
 */
2545 View Code Duplication
function bigbluebutonbn_settings_extended(&$renderer) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
2546
    // Configuration for extended BN capabilities.
2547
    if (!bigbluebuttonbn_is_bn_server()) {
2548
        return;
2549
    }
2550
    // Configuration for 'notify users when recording ready' feature.
2551
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_settings_extended_shown()) {
2552
        $renderer->render_group_header('extended_capabilities');
2553
        // UI for 'notify users when recording ready' feature.
2554
        $renderer->render_group_element('recordingready_enabled',
2555
            $renderer->render_group_element_checkbox('recordingready_enabled', 0));
2556
        // UI for 'register meeting events' feature.
2557
        $renderer->render_group_element('meetingevents_enabled',
2558
            $renderer->render_group_element_checkbox('meetingevents_enabled', 0));
2559
    }
2560
}
2561
2562
/**
2563
 * Helper function returns an encoded meetingid.
2564
 *
2565
 * @param string $seed
2566
 *
2567
 * @return string
2568
 */
2569
function bigbluebuttonbn_encode_meetingid($seed) {
2570
    global $CFG;
2571
    return sha1($CFG->wwwroot . $seed . \mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
2572
}
2573