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

locallib.php ➔ bigbluebuttonbn_event_log_standard()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

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

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
366
    $recordingarray = array('recordID' => (string) $recording->recordID,
367
        'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
368
        'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
369
        'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray);
370
    if (isset($recording->protected)) {
371
        $recordingarray['protected'] = (string) $recording->protected;
372
    }
373
    return $recordingarray + $metadataarray;
374
}
375
376
/**
377
 * Helper function to convert an xml recording metadata object to an array in the format used by the plugin.
378
 *
379
 * @param object $metadata
380
 *
381
 * @return array
382
 */
383
function bigbluebuttonbn_get_recording_array_meta($metadata) {
384
    $metadataarray = array();
385
    foreach ($metadata as $key => $value) {
386
        if (is_object($value)) {
387
            $value = '';
388
        }
389
        $metadataarray['meta_'.$key] = $value;
390
    }
391
    return $metadataarray;
392
}
393
394
/**
395
 * Helper function to sort an array of recordings. It compares the startTime in two recording objecs.
396
 *
397
 * @param object $a
398
 * @param object $b
399
 *
400
 * @return array
401
 */
402
function bigbluebuttonbn_recording_build_sorter($a, $b) {
403
    if ($a['startTime'] < $b['startTime']) {
404
        return -1;
405
    }
406
    if ($a['startTime'] == $b['startTime']) {
407
        return 0;
408
    }
409
    return 1;
410
}
411
412
/**
413
 * Perform deleteRecordings on BBB.
414
 *
415
 * @param string $recordids
416
 *
417
 * @return boolean
418
 */
419 View Code Duplication
function bigbluebuttonbn_delete_recordings($recordids) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
420
    $ids = explode(',', $recordids);
421
    foreach ($ids as $id) {
422
        $xml = bigbluebuttonbn_wrap_xml_load_file(
423
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('deleteRecordings', ['recordID' => $id])
424
          );
425
        if ($xml && $xml->returncode != 'SUCCESS') {
426
            return false;
427
        }
428
    }
429
    return true;
430
}
431
432
/**
433
 * Perform publishRecordings on BBB.
434
 *
435
 * @param string $recordids
436
 * @param string $publish
437
 */
438 View Code Duplication
function bigbluebuttonbn_publish_recordings($recordids, $publish = 'true') {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
439
    $ids = explode(',', $recordids);
440
    foreach ($ids as $id) {
441
        $xml = bigbluebuttonbn_wrap_xml_load_file(
442
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish])
443
          );
444
        if ($xml && $xml->returncode != 'SUCCESS') {
445
            return false;
446
        }
447
    }
448
    return true;
449
}
450
451
/**
452
 * Perform updateRecordings on BBB.
453
 *
454
 * @param string $recordids
455
 * @param array $params ['key'=>param_key, 'value']
456
 */
457 View Code Duplication
function bigbluebuttonbn_update_recordings($recordids, $params) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
458
    $ids = explode(',', $recordids);
459
    foreach ($ids as $id) {
460
        $xml = bigbluebuttonbn_wrap_xml_load_file(
461
            \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('updateRecordings', ['recordID' => $id] + (array) $params)
462
          );
463
        if ($xml && $xml->returncode != 'SUCCESS') {
464
            return false;
465
        }
466
    }
467
    return true;
468
}
469
470
/**
471
 * Perform end on BBB.
472
 *
473
 * @param string $meetingid
474
 * @param string $modpw
475
 */
476
function bigbluebuttonbn_end_meeting($meetingid, $modpw) {
477
    $xml = bigbluebuttonbn_wrap_xml_load_file(
478
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('end', ['meetingID' => $meetingid, 'password' => $modpw])
479
      );
480
    if ($xml) {
481
        // If the xml packet returned failure it displays the message to the user.
482
        return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey);
483
    }
484
    // If the server is unreachable, then prompts the user of the necessary action.
485
    return null;
486
}
487
488
/**
489
 * Perform isMeetingRunning on BBB.
490
 *
491
 * @param string $meetingid
492
 */
493
function bigbluebuttonbn_is_meeting_running($meetingid) {
494
    /* As a workaround to isMeetingRunning that always return SUCCESS but only returns true
495
     * when at least one user is in the session, we use getMeetingInfo instead.
496
     */
497
    $xml = bigbluebuttonbn_wrap_xml_load_file(
498
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
499
      );
500
    return ($xml && $xml->returncode == 'SUCCESS');
501
}
502
503
/**
504
 * Perform api request on BBB.
505
 *
506
 * @return string
507
 */
508
function bigbluebuttonbn_get_server_version() {
509
    $xml = bigbluebuttonbn_wrap_xml_load_file(
510
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url()
511
      );
512
    if ($xml && $xml->returncode == 'SUCCESS') {
513
        return $xml->version;
514
    }
515
    return null;
516
}
517
518
/**
519
 * Perform api request on BBB and wraps the response in an XML object
520
 *
521
 * @param string $url
522
 * @param string $method
523
 * @param string $data
524
 * @param string $contenttype
525
 *
526
 * @return object
527
 */
528
function bigbluebuttonbn_wrap_xml_load_file($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
529
    if (extension_loaded('curl')) {
530
        $response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype);
531
        if (!$response) {
532
            debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER);
533
            return null;
534
        }
535
        $previous = libxml_use_internal_errors(true);
536
        try {
537
            $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
538
            return $xml;
539
        } catch (Exception $e) {
540
            libxml_use_internal_errors($previous);
541
            $error = 'Caught exception: '.$e->getMessage();
542
            debugging($error, DEBUG_DEVELOPER);
543
            return null;
544
        }
545
    }
546
    // Alternative request non CURL based.
547
    $previous = libxml_use_internal_errors(true);
548
    try {
549
        $response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
550
        return $response;
551
    } catch (Exception $e) {
552
        $error = 'Caught exception: '.$e->getMessage();
553
        debugging($error, DEBUG_DEVELOPER);
554
        libxml_use_internal_errors($previous);
555
        return null;
556
    }
557
}
558
559
/**
560
 * Perform api request on BBB using CURL and wraps the response in an XML object
561
 *
562
 * @param string $url
563
 * @param string $method
564
 * @param string $data
565
 * @param string $contenttype
566
 *
567
 * @return object
568
 */
569
function bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method = 'GET', $data = null, $contenttype = 'text/xml') {
570
    $c = new curl();
571
    $c->setopt(array('SSL_VERIFYPEER' => true));
572
    if ($method == 'POST') {
573
        if (is_null($data) || is_array($data)) {
574
            return $c->post($url);
575
        }
576
577
        $options = array();
578
        $options['CURLOPT_HTTPHEADER'] = array(
579
                 'Content-Type: '.$contenttype,
580
                 'Content-Length: '.strlen($data),
581
                 'Content-Language: en-US',
582
               );
583
584
        return $c->post($url, $data, $options);
585
    }
586
    return $c->get($url);
587
}
588
589
/**
590
 * End the session associated with this instance (if it's running).
591
 *
592
 * @param object $bigbluebuttonbn
593
 *
594
 * @return void
595
 */
596
function bigbluebuttonbn_end_meeting_if_running($bigbluebuttonbn) {
597
    $meetingid = $bigbluebuttonbn->meetingid.'-'.$bigbluebuttonbn->course.'-'.$bigbluebuttonbn->id;
598
    if (bigbluebuttonbn_is_meeting_running($meetingid)) {
599
        bigbluebuttonbn_end_meeting($meetingid, $bigbluebuttonbn->moderatorpass);
600
    }
601
}
602
603
/**
604
 * Returns user roles in a context.
605
 *
606
 * @param context $context
607
 * @param context $userid
608
 *
609
 * @return array $userroles
610
 */
611
function bigbluebuttonbn_get_user_roles($context, $userid) {
612
    global $DB;
613
    $userroles = get_user_roles($context, $userid);
614
    if ($userroles) {
615
        $where = '';
616
        foreach ($userroles as $userrole) {
617
            $where .= (empty($where) ? ' WHERE' : ' OR').' id='.$userrole->roleid;
618
        }
619
        $userroles = $DB->get_records_sql('SELECT * FROM {role}'.$where);
620
    }
621
    return $userroles;
622
}
623
624
/**
625
 * Returns guest role wrapped in an array.
626
 *
627
 * @return array
628
 */
629
function bigbluebuttonbn_get_guest_role() {
630
    $guestrole = get_guest_role();
631
    return array($guestrole->id => $guestrole);
632
}
633
634
/**
635
 * Returns an array containing all the users in a context.
636
 *
637
 * @param context $context
638
 *
639
 * @return array $users
640
 */
641
function bigbluebuttonbn_get_users(context $context = null) {
642
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
643
    foreach ($users as $key => $value) {
644
        $users[$key] = fullname($value);
645
    }
646
    return $users;
647
}
648
649
/**
650
 * Returns an array containing all the users in a context wrapped for html select element.
651
 *
652
 * @param context $context
653
 *
654
 * @return array $users
655
 */
656
function bigbluebuttonbn_get_users_select(context $context = null) {
657
    $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
658
    foreach ($users as $key => $value) {
659
        $users[$key] = array('id' => $value->id, 'name' => fullname($value));
660
    }
661
    return $users;
662
}
663
664
/**
665
 * Returns an array containing all the roles in a context.
666
 *
667
 * @param context $context
668
 *
669
 * @return array $roles
670
 */
671
function bigbluebuttonbn_get_roles(context $context = null) {
672
    $roles = (array) role_get_names($context);
673
    foreach ($roles as $key => $value) {
674
        $roles[$key] = $value->localname;
675
    }
676
    return $roles;
677
}
678
679
/**
680
 * Returns an array containing all the roles in a context wrapped for html select element.
681
 *
682
 * @param context $context
683
 *
684
 * @return array $users
685
 */
686
function bigbluebuttonbn_get_roles_select(context $context = null) {
687
    $roles = (array) role_get_names($context);
688
    foreach ($roles as $key => $value) {
689
        $roles[$key] = array('id' => $value->id, 'name' => $value->localname);
690
    }
691
    return $roles;
692
}
693
694
/**
695
 * Returns role that corresponds to an id.
696
 *
697
 * @param string|integer $id
698
 *
699
 * @return object $role
700
 */
701
function bigbluebuttonbn_get_role($id) {
702
    $roles = (array) role_get_names();
703
    if (is_numeric($id)) {
704
        return (object)$roles[$id];
705
    }
706
    foreach ($roles as $role) {
707
        if ($role->shortname == $id) {
708
            return $role;
709
        }
710
    }
711
}
712
713
/**
714
 * Returns an array to populate a list of participants used in mod_form.js.
715
 *
716
 * @param context $context
717
 *
718
 * @return array $data
719
 */
720
function bigbluebuttonbn_get_participant_data($context) {
721
    $data = array(
722
        'all' => array(
723
            'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
724
            'children' => []
725
          )
726
      );
727
    $data['role'] = array(
728
        'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
729
        'children' => bigbluebuttonbn_get_roles_select($context)
730
      );
731
    $data['user'] = array(
732
        'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
733
        'children' => bigbluebuttonbn_get_users_select($context)
734
      );
735
    return $data;
736
}
737
738
/**
739
 * Returns an array to populate a list of participants used in mod_form.php.
740
 *
741
 * @param object $bigbluebuttonbn
742
 * @param context $context
743
 *
744
 * @return array
745
 */
746
function bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context) {
747
    if ($bigbluebuttonbn == null) {
748
        return bigbluebuttonbn_get_participant_list_default($context);
749
    }
750
    return bigbluebuttonbn_get_participant_rules_encoded($bigbluebuttonbn);
751
}
752
753
/**
754
 * Returns an array to populate a list of participants used in mod_form.php with default values.
755
 *
756
 * @param context $context
757
 *
758
 * @return array
759
 */
760
function bigbluebuttonbn_get_participant_list_default($context) {
761
    global $USER;
762
    $participantlistarray = array();
763
    $participantlistarray[] = array(
764
        'selectiontype' => 'all',
765
        'selectionid' => 'all',
766
        'role' => BIGBLUEBUTTONBN_ROLE_VIEWER);
767
    $moderatordefaults = explode(',', \mod_bigbluebuttonbn\locallib\config::get('participant_moderator_default'));
768
    foreach ($moderatordefaults as $moderatordefault) {
769
        if ($moderatordefault == '0') {
770
            if (is_enrolled($context, $USER->id)) {
771
                $participantlistarray[] = array(
772
                    'selectiontype' => 'user',
773
                    'selectionid' => $USER->id,
774
                    'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
775
            }
776
            continue;
777
        }
778
        $participantlistarray[] = array(
779
              'selectiontype' => 'role',
780
              'selectionid' => $moderatordefault,
781
              'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR);
782
    }
783
    return $participantlistarray;
784
}
785
786
/**
787
 * Returns an array to populate a list of participants used in mod_form.php with bigbluebuttonbn values.
788
 *
789
 * @param object $bigbluebuttonbn
790
 *
791
 * @return array
792
 */
793
function bigbluebuttonbn_get_participant_rules_encoded($bigbluebuttonbn) {
794
    $rules = json_decode($bigbluebuttonbn->participants, true);
795
    if (!is_array($rules)) {
796
        return array();
797
    }
798
    foreach ($rules as $key => $rule) {
799
        if ( $rule['selectiontype'] !== 'role' || is_numeric($rule['selectionid']) ) {
800
            continue;
801
        }
802
        $role = bigbluebuttonbn_get_role($rule['selectionid']);
803
        if ( $role == null ) {
804
            unset($rules[$key]);
805
            continue;
806
        }
807
        $rule['selectionid'] = $role->id;
808
        $rules[$key] = $rule;
809
    }
810
    return $rules;
811
}
812
813
/**
814
 * Returns an array to populate a list of participant_selection used in mod_form.php.
815
 *
816
 * @return array
817
 */
818
function bigbluebuttonbn_get_participant_selection_data() {
819
    return [
820
        'type_options' => [
821
            'all' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
822
            'role' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
823
            'user' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
824
          ],
825
        'type_selected' => 'all',
826
        'options' => ['all' => '---------------'],
827
        'selected' => 'all',
828
      ];
829
}
830
831
/**
832
 * Evaluate if a user in a context is moderator based on roles and participation rules.
833
 *
834
 * @param context $context
835
 * @param string $participants
836
 * @param integer $userid
837
 * @param array $userroles
838
 *
839
 * @return boolean
840
 */
841
function bigbluebuttonbn_is_moderator($context, $participants, $userid = null, $userroles = null) {
842
    global $USER;
843
    if (empty($participants)) {
844
        // The room that is being used comes from a previous version.
845
        return has_capability('mod/bigbluebuttonbn:moderate', $context);
846
    }
847
    $participantlist = json_decode($participants);
848
    if (!is_array($participantlist)) {
849
        return false;
850
    }
851
    if (empty($userid)) {
852
        $userid = $USER->id;
853
    }
854
    if (empty($userroles)) {
855
        $userroles = get_user_roles($context, $userid, true);
856
    }
857
    return bigbluebuttonbn_is_moderator_validator($participantlist, $userid , $userroles);
858
}
859
860
/**
861
 * Iterates participant list rules to evaluate if a user is moderator.
862
 *
863
 * @param array $participantlist
864
 * @param integer $userid
865
 * @param array $userroles
866
 *
867
 * @return boolean
868
 */
869
function bigbluebuttonbn_is_moderator_validator($participantlist, $userid, $userroles) {
870
    // Iterate participant rules.
871
    foreach ($participantlist as $participant) {
872
        if (bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles)) {
873
            return true;
874
        }
875
    }
876
    return false;
877
}
878
879
/**
880
 * Evaluate if a user is moderator based on roles and a particular participation rule.
881
 *
882
 * @param object $participant
883
 * @param integer $userid
884
 * @param array $userroles
885
 *
886
 * @return boolean
887
 */
888
function bigbluebuttonbn_is_moderator_validate_rule($participant, $userid, $userroles) {
889
    if ($participant->role == BIGBLUEBUTTONBN_ROLE_VIEWER) {
890
        return false;
891
    }
892
    // Looks for all configuration.
893
    if ($participant->selectiontype == 'all') {
894
        return true;
895
    }
896
    // Looks for users.
897
    if ($participant->selectiontype == 'user' && $participant->selectionid == $userid) {
898
        return true;
899
    }
900
    // Looks for roles.
901
    $role = bigbluebuttonbn_get_role($participant->selectionid);
902
    if (array_key_exists($role->id, $userroles)) {
903
        return true;
904
    }
905
    return false;
906
}
907
908
/**
909
 * Helper returns error message key for the language file that corresponds to a bigbluebutton error key.
910
 *
911
 * @param string $messagekey
912
 * @param string $defaultkey
913
 *
914
 * @return string
915
 */
916
function bigbluebuttonbn_get_error_key($messagekey, $defaultkey = null) {
917
    if ($messagekey == 'checksumError') {
918
        return 'index_error_checksum';
919
    }
920
    if ($messagekey == 'maxConcurrent') {
921
        return 'view_error_max_concurrent';
922
    }
923
    return $defaultkey;
924
}
925
926
/**
927
 * Helper evaluates if a voicebridge number is unique.
928
 *
929
 * @param integer $voicebridge
930
 *
931
 * @return string
932
 */
933
function bigbluebuttonbn_voicebridge_unique($voicebridge) {
934
    global $DB;
935
    if ($voicebridge != 0) {
936
        $table = 'bigbluebuttonbn';
937
        $select = 'voicebridge = '.$voicebridge;
938
        if ($DB->get_records_select($table, $select)) {
939
            return false;
940
        }
941
    }
942
    return true;
943
}
944
945
/**
946
 * Helper estimate a duration for the meeting based on the closingtime.
947
 *
948
 * @param integer $closingtime
949
 *
950
 * @return integer
951
 */
952
function bigbluebuttonbn_get_duration($closingtime) {
953
    $duration = 0;
954
    $now = time();
955
    if ($closingtime > 0 && $now < $closingtime) {
956
        $duration = ceil(($closingtime - $now) / 60);
957
        $compensationtime = intval((int)\mod_bigbluebuttonbn\locallib\config::get('scheduled_duration_compensation'));
958
        $duration = intval($duration) + $compensationtime;
959
    }
960
    return $duration;
961
}
962
963
/**
964
 * Helper return array containing the file descriptor for a preuploaded presentation.
965
 *
966
 * @param context $context
967
 * @param string $presentation
968
 * @param integer $id
969
 *
970
 * @return array
971
 */
972
function bigbluebuttonbn_get_presentation_array($context, $presentation, $id = null) {
973
    if (empty($presentation)) {
974
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
975
    }
976
    $fs = get_file_storage();
977
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
978
        'itemid, filepath, filename', false);
979
    if (count($files) == 0) {
980
        return array('url' => null, 'name' => null, 'icon' => null, 'mimetype_description' => null);
981
    }
982
    $file = reset($files);
983
    unset($files);
984
    $pnoncevalue = null;
985
    if (!is_null($id)) {
986
        // Create the nonce component for granting a temporary public access.
987
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn',
988
            'presentation_cache');
989
        $pnoncekey = sha1($id);
990
        /* The item id was adapted for granting public access to the presentation once in order
991
         * to allow BigBlueButton to gather the file. */
992
        $pnoncevalue = bigbluebuttonbn_generate_nonce();
993
        $cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0));
994
    }
995
    $url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
996
        $file->get_filearea(), $pnoncevalue, $file->get_filepath(), $file->get_filename());
997
    return array('name' => $file->get_filename(), 'icon' => file_file_icon($file, 24),
998
            'url' => $url->out(false), 'mimetype_description' => get_mimetype_description($file));
999
}
1000
1001
/**
1002
 * Helper generates a nonce used for the preuploaded presentation callback url.
1003
 *
1004
 * @return string
1005
 */
1006
function bigbluebuttonbn_generate_nonce() {
1007
    $mt = microtime();
1008
    $rand = mt_rand();
1009
    return md5($mt.$rand);
1010
}
1011
1012
/**
1013
 * Helper generates a random password.
1014
 *
1015
 * @param integer $length
1016
 * @param string $unique
1017
 *
1018
 * @return string
1019
 */
1020
function bigbluebuttonbn_random_password($length = 8, $unique = "") {
1021
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?';
1022
    do {
1023
        $password = substr(str_shuffle($chars), 0, $length);
1024
    } while ($unique == $password);
1025
    return $password;
1026
}
1027
1028
/**
1029
 * Helper returns an array with all possible bigbluebuttonbn events.
1030
 *
1031
 * @return array
1032
 */
1033
function bigbluebuttonbn_events() {
1034
    return array(
1035
        (string) BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED,
1036
        (string) BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED,
1037
        (string) BIGBLUEBUTTON_EVENT_LIVE_SESSION,
1038
        (string) BIGBLUEBUTTON_EVENT_MEETING_CREATED,
1039
        (string) BIGBLUEBUTTON_EVENT_MEETING_ENDED,
1040
        (string) BIGBLUEBUTTON_EVENT_MEETING_JOINED,
1041
        (string) BIGBLUEBUTTON_EVENT_MEETING_LEFT,
1042
        (string) BIGBLUEBUTTON_EVENT_RECORDING_DELETED,
1043
        (string) BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED,
1044
        (string) BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED,
1045
        (string) BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED,
1046
        (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED,
1047
        (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED,
1048
        (string) BIGBLUEBUTTON_EVENT_RECORDING_EDITED,
1049
        (string) BIGBLUEBUTTON_EVENT_RECORDING_VIEWED
1050
    );
1051
}
1052
1053
/**
1054
 * Helper returns an array with the actions and their corresponding bigbluebuttonbn events.
1055
 *
1056
 * @return array
1057
 */
1058
function bigbluebuttonbn_events_action() {
1059
    return array(
1060
        'view' => (string) BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED,
1061
        'view_management' => (string) BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED,
1062
        'live_action' => (string) BIGBLUEBUTTON_EVENT_LIVE_SESSION,
1063
        'meeting_create' => (string) BIGBLUEBUTTON_EVENT_MEETING_CREATED,
1064
        'meeting_end' => (string) BIGBLUEBUTTON_EVENT_MEETING_ENDED,
1065
        'meeting_join' => (string) BIGBLUEBUTTON_EVENT_MEETING_JOINED,
1066
        'meeting_left' => (string) BIGBLUEBUTTON_EVENT_MEETING_LEFT,
1067
        'recording_delete' => (string) BIGBLUEBUTTON_EVENT_RECORDING_DELETED,
1068
        'recording_import' => (string) BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED,
1069
        'recording_protect' => (string) BIGBLUEBUTTON_EVENT_RECORDING_PROTECTED,
1070
        'recording_publish' => (string) BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED,
1071
        'recording_unprotect' => (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPROTECTED,
1072
        'recording_unpublish' => (string) BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED,
1073
        'recording_edit' => (string) BIGBLUEBUTTON_EVENT_RECORDING_EDITED,
1074
        'recording_play' => (string) BIGBLUEBUTTON_EVENT_RECORDING_VIEWED
1075
    );
1076
}
1077
1078
/**
1079
 * Helper register a bigbluebuttonbn event.
1080
 *
1081
 * @param string $eventtype
1082
 * @param object $bigbluebuttonbn
1083
 * @param object $cm
1084
 * @param array $options
1085
 *
1086
 * @return void
1087
 */
1088
function bigbluebuttonbn_event_log($eventtype, $bigbluebuttonbn, $cm, $options = []) {
1089
    $events = bigbluebuttonbn_events();
1090
    if (!in_array($eventtype, $events)) {
1091
        // No log will be created.
1092
        return;
1093
    }
1094
    $context = context_module::instance($cm->id);
1095
    $eventproperties = array('context' => $context, 'objectid' => $bigbluebuttonbn->id);
1096
    if (array_key_exists('timecreated', $options)) {
1097
        $eventproperties['timecreated'] = $options['timecreated'];
1098
    }
1099
    if (array_key_exists('userid', $options)) {
1100
        $eventproperties['userid'] = $options['userid'];
1101
    }
1102
    if (array_key_exists('other', $options)) {
1103
        $eventproperties['other'] = $options['other'];
1104
    }
1105
    $event = call_user_func_array('\mod_bigbluebuttonbn\event\bigbluebuttonbn_'.$eventtype.'::create',
1106
      array($eventproperties));
1107
    $event->trigger();
1108
}
1109
1110
/**
1111
 * Updates the meeting info cached object when a participant has joined.
1112
 *
1113
 * @param string $meetingid
1114
 * @param bool $ismoderator
1115
 *
1116
 * @return void
1117
 */
1118
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) {
1119
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1120
    $result = $cache->get($meetingid);
1121
    $meetinginfo = json_decode($result['meeting_info']);
1122
    $meetinginfo->participantCount += 1;
1123
    if ($ismoderator) {
1124
        $meetinginfo->moderatorCount += 1;
1125
    }
1126
    $cache->set($meetingid, array('creation_time' => $result['creation_time'],
1127
        'meeting_info' => json_encode($meetinginfo)));
1128
}
1129
1130
/**
1131
 * Gets a meeting info object cached or fetched from the live session.
1132
 *
1133
 * @param string $meetingid
1134
 * @param boolean $updatecache
1135
 *
1136
 * @return array
1137
 */
1138
function bigbluebuttonbn_get_meeting_info($meetingid, $updatecache = false) {
1139
    $cachettl = (int)\mod_bigbluebuttonbn\locallib\config::get('waitformoderator_cache_ttl');
1140
    $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
1141
    $result = $cache->get($meetingid);
1142
    $now = time();
1143
    if (!$updatecache && isset($result) && $now < ($result['creation_time'] + $cachettl)) {
1144
        // Use the value in the cache.
1145
        return (array) json_decode($result['meeting_info']);
1146
    }
1147
    // Ping again and refresh the cache.
1148
    $meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file(
1149
        \mod_bigbluebuttonbn\locallib\bigbluebutton::action_url('getMeetingInfo', ['meetingID' => $meetingid])
1150
      );
1151
    $cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo)));
1152
    return $meetinginfo;
1153
}
1154
1155
/**
1156
 * Publish an imported recording.
1157
 *
1158
 * @param string $id
1159
 * @param boolean $publish
1160
 *
1161
 * @return boolean
1162
 */
1163 View Code Duplication
function bigbluebuttonbn_publish_recording_imported($id, $publish = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
1164
    global $DB;
1165
    // Locate the record to be updated.
1166
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1167
    $meta = json_decode($record->meta, true);
1168
    // Prepare data for the update.
1169
    $meta['recording']['published'] = ($publish) ? 'true' : 'false';
1170
    $record->meta = json_encode($meta);
1171
    // Proceed with the update.
1172
    $DB->update_record('bigbluebuttonbn_logs', $record);
1173
    return true;
1174
}
1175
1176
/**
1177
 * Delete an imported recording.
1178
 *
1179
 * @param string $id
1180
 *
1181
 * @return boolean
1182
 */
1183
function bigbluebuttonbn_delete_recording_imported($id) {
1184
    global $DB;
1185
    // Execute delete.
1186
    $DB->delete_records('bigbluebuttonbn_logs', array('id' => $id));
1187
    return true;
1188
}
1189
1190
/**
1191
 * Update an imported recording.
1192
 *
1193
 * @param string $id
1194
 * @param array $params ['key'=>param_key, 'value']
1195
 *
1196
 * @return boolean
1197
 */
1198
function bigbluebuttonbn_update_recording_imported($id, $params) {
1199
    global $DB;
1200
    // Locate the record to be updated.
1201
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1202
    $meta = json_decode($record->meta, true);
1203
    // Prepare data for the update.
1204
    $meta['recording'] = $params + $meta['recording'];
1205
    $record->meta = json_encode($meta);
1206
    // Proceed with the update.
1207
    if (!$DB->update_record('bigbluebuttonbn_logs', $record)) {
1208
        return false;
1209
    }
1210
    return true;
1211
}
1212
1213
/**
1214
 * Protect/Unprotect an imported recording.
1215
 *
1216
 * @param string $id
1217
 * @param boolean $protect
1218
 *
1219
 * @return boolean
1220
 */
1221 View Code Duplication
function bigbluebuttonbn_protect_recording_imported($id, $protect = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
1222
    global $DB;
1223
    // Locate the record to be updated.
1224
    $record = $DB->get_record('bigbluebuttonbn_logs', array('id' => $id));
1225
    $meta = json_decode($record->meta, true);
1226
    // Prepare data for the update.
1227
    $meta['recording']['protected'] = ($protect) ? 'true' : 'false';
1228
    $record->meta = json_encode($meta);
1229
    // Proceed with the update.
1230
    $DB->update_record('bigbluebuttonbn_logs', $record);
1231
    return true;
1232
}
1233
1234
/**
1235
 * Sets a custom config.xml file for being used on create.
1236
 *
1237
 * @param string $meetingid
1238
 * @param string $configxml
1239
 *
1240
 * @return object
1241
 */
1242
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) {
1243
    $urldefaultconfig = \mod_bigbluebuttonbn\locallib\config::get('server_url').'api/setConfigXML?';
1244
    $configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml);
1245
    $xml = bigbluebuttonbn_wrap_xml_load_file($urldefaultconfig, 'POST',
1246
        $configxmlparams, 'application/x-www-form-urlencoded');
1247
    return $xml;
1248
}
1249
1250
/**
1251
 * Sets qs used with a custom config.xml file request.
1252
 *
1253
 * @param string $meetingid
1254
 * @param string $configxml
1255
 *
1256
 * @return string
1257
 */
1258
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) {
1259
    $params = 'configXML='.urlencode($configxml).'&meetingID='.urlencode($meetingid);
1260
    $configxmlparams = $params.'&checksum='.sha1('setConfigXML'.$params.\mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
1261
    return $configxmlparams;
1262
}
1263
1264
/**
1265
 * Sets a custom config.xml file for being used on create.
1266
 *
1267
 * @param string $meetingid
1268
 * @param string $configxml
1269
 *
1270
 * @return array
1271
 */
1272
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) {
1273
    $configxml = bigbluebuttonbn_setConfigXML($meetingid, $configxml);
1274
    $configxmlarray = (array) $configxml;
1275
    if ($configxmlarray['returncode'] != 'SUCCESS') {
1276
        debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER);
1277
        return '';
1278
    }
1279
    return $configxmlarray['configToken'];
1280
}
1281
1282
/**
1283
 * Helper function builds a row for the data used by the recording table.
1284
 *
1285
 * @param array $bbbsession
1286
 * @param array $recording
1287
 * @param array $tools
1288
 *
1289
 * @return array
1290
 */
1291
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['protect', 'publish', 'delete']) {
1292
    if (!$bbbsession['managerecordings'] && $recording['published'] != 'true') {
1293
        return;
1294
    }
1295
    $editable = bigbluebuttonbn_get_recording_data_row_editable($bbbsession);
1296
    $row = new stdClass();
1297
    // Set recording_types.
1298
    $row->recording = bigbluebuttonbn_get_recording_data_row_types($recording, $bbbsession['bigbluebuttonbn']->id);
1299
    // Set activity name.
1300
    $row->activity = bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $editable);
1301
    // Set activity description.
1302
    $row->description = bigbluebuttonbn_get_recording_data_row_meta_description($recording, $editable);
1303
    // Set recording_preview.
1304
    $row->preview = bigbluebuttonbn_get_recording_data_row_preview($recording);
1305
    // Set date.
1306
    $row->date = bigbluebuttonbn_get_recording_data_row_date($recording);
1307
    // Set formatted date.
1308
    $row->date_formatted = bigbluebuttonbn_get_recording_data_row_date_formatted($row->date);
1309
    // Set formatted duration.
1310
    $row->duration_formatted = $row->duration = bigbluebuttonbn_get_recording_data_row_duration($recording);
1311
    // Set actionbar, if user is allowed to manage recordings.
1312
    if ($bbbsession['managerecordings']) {
1313
        $row->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools);
1314
    }
1315
    return $row;
1316
}
1317
1318
/**
1319
 * Helper function evaluates if a row for the data used by the recording table is editable.
1320
 *
1321
 * @param array $bbbsession
1322
 *
1323
 * @return boolean
1324
 */
1325
function bigbluebuttonbn_get_recording_data_row_editable($bbbsession) {
1326
    return ($bbbsession['managerecordings'] && ((double)$bbbsession['serverversion'] >= 1.0 || bigbluebuttonbn_is_bn_server()));
1327
}
1328
1329
/**
1330
 * Helper function converts recording date used in row for the data used by the recording table.
1331
 *
1332
 * @param array $recording
1333
 *
1334
 * @return integer
1335
 */
1336
function bigbluebuttonbn_get_recording_data_row_date($recording) {
1337
    if (!isset($recording['startTime'])) {
1338
        return 0;
1339
    }
1340
    return floatval($recording['startTime']);
1341
}
1342
1343
/**
1344
 * Helper function format recording date used in row for the data used by the recording table.
1345
 *
1346
 * @param integer $starttime
1347
 *
1348
 * @return string
1349
 */
1350
function bigbluebuttonbn_get_recording_data_row_date_formatted($starttime) {
1351
    global $USER;
1352
    $starttime = $starttime - ($starttime % 1000);
1353
    // Set formatted date.
1354
    $dateformat = get_string('strftimerecentfull', 'langconfig').' %Z';
1355
    return userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone));
1356
}
1357
1358
/**
1359
 * Helper function converts recording duration used in row for the data used by the recording table.
1360
 *
1361
 * @param array $recording
1362
 *
1363
 * @return integer
1364
 */
1365
function bigbluebuttonbn_get_recording_data_row_duration($recording) {
1366
    $firstplayback = array_values($recording['playbacks'])[0];
1367
    $length = 0;
1368
    if (isset($firstplayback['length'])) {
1369
        $length = $firstplayback['length'];
1370
    }
1371
    return intval($length);
1372
}
1373
1374
/**
1375
 * Helper function builds recording actionbar used in row for the data used by the recording table.
1376
 *
1377
 * @param array $recording
1378
 * @param array $tools
1379
 *
1380
 * @return string
1381
 */
1382
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) {
1383
    $actionbar = '';
1384
    foreach ($tools as $tool) {
1385
        if ( $tool == 'protect' && !isset($recording['protected']) ) {
1386
            continue;
1387
        }
1388
        $buttonpayload = bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool);
1389
        $actionbar .= bigbluebuttonbn_actionbar_render_button($recording, $buttonpayload);
1390
    }
1391
    $head = html_writer::start_tag('div', array(
1392
        'id' => 'recording-actionbar-' . $recording['recordID'],
1393
        'data-recordingid' => $recording['recordID'],
1394
        'data-meetingid' => $recording['meetingID']));
1395
    $tail = html_writer::end_tag('div');
1396
    return $head . $actionbar . $tail;
1397
}
1398
1399
/**
1400
 * Helper function returns the corresponding payload for an actionbar button used in row
1401
 * for the data used by the recording table.
1402
 *
1403
 * @param array $recording
1404
 * @param array $tool
1405
 *
1406
 * @return array
1407
 */
1408
function bigbluebuttonbn_get_recording_data_row_actionbar_payload($recording, $tool) {
1409
    if ($tool == 'protect') {
1410
        return bigbluebuttonbn_get_recording_data_row_action_protect($recording['protected']);
1411
    }
1412
    if ($tool == 'publish') {
1413
        return bigbluebuttonbn_get_recording_data_row_action_publish($recording['published']);
1414
    }
1415
    return array('action' => $tool, 'tag' => $tool);
1416
}
1417
1418
/**
1419
 * Helper function returns the payload for protect action button used in row
1420
 * for the data used by the recording table.
1421
 *
1422
 * @param string $protected
1423
 *
1424
 * @return array
1425
 */
1426
function bigbluebuttonbn_get_recording_data_row_action_protect($protected) {
1427
    if ($protected == 'true') {
1428
        return array('action' => 'unprotect', 'tag' => 'lock');
1429
    }
1430
    return array('action' => 'protect', 'tag' => 'unlock');
1431
}
1432
1433
/**
1434
 * Helper function returns the payload for publish action button used in row
1435
 * for the data used by the recording table.
1436
 *
1437
 * @param string $published
1438
 *
1439
 * @return array
1440
 */
1441
function bigbluebuttonbn_get_recording_data_row_action_publish($published) {
1442
    if ($published == 'true') {
1443
        return array('action' => 'unpublish', 'tag' => 'hide');
1444
    }
1445
    return array('action' => 'publish', 'tag' => 'show');
1446
}
1447
1448
/**
1449
 * Helper function builds recording preview used in row for the data used by the recording table.
1450
 *
1451
 * @param array $recording
1452
 *
1453
 * @return string
1454
 */
1455
function bigbluebuttonbn_get_recording_data_row_preview($recording) {
1456
    $visibility = '';
1457
    if ($recording['published'] === 'false') {
1458
        $visibility = 'hidden ';
1459
    }
1460
    $recordingpreview = html_writer::start_tag('div',
1461
        array('id' => 'preview-'.$recording['recordID'], $visibility => $visibility));
1462
    foreach ($recording['playbacks'] as $playback) {
1463
        if (isset($playback['preview'])) {
1464
            foreach ($playback['preview'] as $image) {
1465
                $recordingpreview .= html_writer::empty_tag('img',
1466
                    array('src' => trim($image['url']) . '?' . time(), 'class' => 'thumbnail'));
1467
            }
1468
            $recordingpreview .= html_writer::empty_tag('br');
1469
            $recordingpreview .= html_writer::tag('div',
1470
                get_string('view_recording_preview_help', 'bigbluebuttonbn'), array('class' => 'text-muted small'));
1471
            break;
1472
        }
1473
    }
1474
    $recordingpreview .= html_writer::end_tag('div');
1475
    return $recordingpreview;
1476
}
1477
1478
/**
1479
 * Helper function renders recording types to be used in row for the data used by the recording table.
1480
 *
1481
 * @param array $recording
1482
 * @param integer $bigbluebuttonbnid
1483
 *
1484
 * @return string
1485
 */
1486
function bigbluebuttonbn_get_recording_data_row_types($recording, $bigbluebuttonbnid) {
1487
    $dataimported = 'false';
1488
    $title = '';
1489
    if (isset($recording['imported'])) {
1490
        $dataimported = 'true';
1491
        $title = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1492
    }
1493
    $visibility = '';
1494
    if ($recording['published'] === 'false') {
1495
        $visibility = 'hidden ';
1496
    }
1497
    $id = 'playbacks-'.$recording['recordID'];
1498
    $recordingtypes = html_writer::start_tag('div', array('id' => $id, 'data-imported' => $dataimported,
1499
          'data-meetingid' => $recording['meetingID'], 'data-recordingid' => $recording['recordID'],
1500
          'title' => $title, $visibility => $visibility));
1501
    foreach ($recording['playbacks'] as $playback) {
1502
        $recordingtypes .= bigbluebuttonbn_get_recording_data_row_type($recording, $bigbluebuttonbnid,
1503
            $playback).'&#32;';
1504
    }
1505
    $recordingtypes .= html_writer::end_tag('div');
1506
    return $recordingtypes;
1507
}
1508
1509
/**
1510
 * Helper function renders the link used for recording type in row for the data used by the recording table.
1511
 *
1512
 * @param array $recording
1513
 * @param integer $bigbluebuttonbnid
1514
 * @param array $playback
1515
 *
1516
 * @return string
1517
 */
1518
function bigbluebuttonbn_get_recording_data_row_type($recording, $bigbluebuttonbnid, $playback) {
1519
    global $CFG, $OUTPUT;
1520
    $title = get_string('view_recording_format_'.$playback['type'], 'bigbluebuttonbn');
1521
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recordingPlay(this);';
1522
    $href = $CFG->wwwroot.'/mod/bigbluebuttonbn/bbb_view.php?action=play&bn='.$bigbluebuttonbnid.
1523
      '&mid='.$recording['meetingID'].'&rid='.$recording['recordID'].'&rtype='.$playback['type'];
1524
    if (!isset($recording['imported']) || !isset($recording['protected']) || $recording['protected'] === 'false') {
1525
        $href .= '&href='.urlencode(trim($playback['url']));
1526
    }
1527
    $id = 'recording-play-' . $playback['type'] . '-' . $recording['recordID'];
1528
    $linkattributes = array(
1529
        'id' => $id,
1530
        'onclick' => $onclick,
1531
        'data-action' => 'play',
1532
        'data-target' => $playback['type'],
1533
        'data-href' => $href,
1534
        'class' => 'btn btn-sm btn-default'
1535
      );
1536
    return $OUTPUT->action_link('#', $title, null, $linkattributes);
1537
}
1538
1539
/**
1540
 * Helper function renders the name for recording used in row for the data used by the recording table.
1541
 *
1542
 * @param array $recording
1543
 * @param boolean $editable
1544
 *
1545
 * @return string
1546
 */
1547
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording, $editable) {
1548
    $payload = array();
1549 View Code Duplication
    if ($editable) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1550
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1551
            'action' => 'edit', 'tag' => 'edit',
1552
            'target' => 'name');
1553
    }
1554
    $oldsource = 'meta_contextactivity';
1555 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...
1556
        $metaname = trim($recording[$oldsource]);
1557
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $oldsource, $payload);
1558
    }
1559
    $newsource = 'meta_bbb-recording-name';
1560 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...
1561
        $metaname = trim($recording[$newsource]);
1562
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1563
    }
1564
    $metaname = trim($recording['meetingName']);
1565
    return bigbluebuttonbn_get_recording_data_row_text($recording, $metaname, $newsource, $payload);
1566
}
1567
1568
/**
1569
 * Helper function renders the description for recording used in row for the data used by the recording table.
1570
 *
1571
 * @param array $recording
1572
 * @param boolean $editable
1573
 *
1574
 * @return string
1575
 */
1576
function bigbluebuttonbn_get_recording_data_row_meta_description($recording, $editable) {
1577
    $payload = array();
1578 View Code Duplication
    if ($editable) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1579
        $payload = array('recordingid' => $recording['recordID'], 'meetingid' => $recording['meetingID'],
1580
            'action' => 'edit', 'tag' => 'edit',
1581
            'target' => 'description');
1582
    }
1583
    $oldsource = 'meta_contextactivitydescription';
1584 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...
1585
        $metadescription = trim($recording[$oldsource]);
1586
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $oldsource, $payload);
1587
    }
1588
    $newsource = 'meta_bbb-recording-description';
1589
    if (isset($recording[$newsource])) {
1590
        $metadescription = trim($recording[$newsource]);
1591
        return bigbluebuttonbn_get_recording_data_row_text($recording, $metadescription, $newsource, $payload);
1592
    }
1593
    return bigbluebuttonbn_get_recording_data_row_text($recording, '', $newsource, $payload);
1594
}
1595
1596
/**
1597
 * Helper function renders text element for recording used in row for the data used by the recording table.
1598
 *
1599
 * @param array $recording
1600
 * @param string $text
1601
 * @param string $source
1602
 * @param array $data
1603
 *
1604
 * @return string
1605
 */
1606
function bigbluebuttonbn_get_recording_data_row_text($recording, $text, $source, $data) {
1607
    $htmltext = '<span>' . htmlentities($text) . '</span>';
1608
    if (empty($data)) {
1609
        return $htmltext;
1610
    }
1611
    $target = $data['action'] . '-' . $data['target'];
1612
    $id = 'recording-' . $target . '-' . $data['recordingid'];
1613
    $attributes = array('id' => $id, 'class' => 'quickeditlink col-md-20',
1614
        'data-recordingid' => $data['recordingid'], 'data-meetingid' => $data['meetingid'],
1615
        'data-target' => $data['target'], 'data-source' => $source);
1616
    $head = html_writer::start_tag('div', $attributes);
1617
    $tail = html_writer::end_tag('div');
1618
    $payload = array('action' => $data['action'], 'tag' => $data['tag'], 'target' => $data['target']);
1619
    $htmllink = bigbluebuttonbn_actionbar_render_button($recording, $payload);
1620
    return $head . $htmltext . $htmllink . $tail;
1621
}
1622
1623
/**
1624
 * Helper function render a button for the recording action bar
1625
 *
1626
 * @param array $recording
1627
 * @param array $data
1628
 *
1629
 * @return string
1630
 */
1631
function bigbluebuttonbn_actionbar_render_button($recording, $data) {
1632
    global $OUTPUT;
1633
    if (empty($data)) {
1634
        return '';
1635
    }
1636
    $target = $data['action'];
1637
    if (isset($data['target'])) {
1638
        $target .= '-' . $data['target'];
1639
    }
1640
    $id = 'recording-' . $target . '-' . $recording['recordID'];
1641
    $onclick = 'M.mod_bigbluebuttonbn.recordings.recording' . ucfirst($data['action']) . '(this);';
1642
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::get('recording_icons_enabled')) {
1643
        // With icon for $manageaction.
1644
        $iconattributes = array('id' => $id, 'class' => 'iconsmall');
1645
        $icon = new pix_icon('i/'.$data['tag'],
1646
            get_string('view_recording_list_actionbar_' . $data['action'], 'bigbluebuttonbn'),
1647
            'moodle', $iconattributes);
1648
        $linkattributes = array(
1649
            'id' => $id,
1650
            'onclick' => $onclick,
1651
            'data-action' => $data['action'],
1652
            'data-links' => bigbluebuttonbn_get_count_recording_imported_instances($recording['recordID'])
1653
          );
1654
        return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false);
1655
    }
1656
    // With text for $manageaction.
1657
    $linkattributes = array('title' => get_string($data['tag']), 'class' => 'btn btn-xs btn-danger',
1658
        'onclick' => $onclick);
1659
    return $OUTPUT->action_link('#', get_string($data['action']), null, $linkattributes);
1660
}
1661
1662
/**
1663
 * Helper function builds the data used for headers by the recording table.
1664
 *
1665
 * @param array $bbbsession
1666
 *
1667
 * @return array
1668
 */
1669
function bigbluebuttonbn_get_recording_columns($bbbsession) {
1670
    // Set strings to show.
1671
    $recording = get_string('view_recording_recording', 'bigbluebuttonbn');
1672
    $activity = get_string('view_recording_activity', 'bigbluebuttonbn');
1673
    $description = get_string('view_recording_description', 'bigbluebuttonbn');
1674
    $preview = get_string('view_recording_preview', 'bigbluebuttonbn');
1675
    $date = get_string('view_recording_date', 'bigbluebuttonbn');
1676
    $duration = get_string('view_recording_duration', 'bigbluebuttonbn');
1677
    $actionbar = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1678
    // Initialize table headers.
1679
    $recordingsbncolumns = array(
1680
        array('key' => 'recording', 'label' => $recording, 'width' => '125px', 'allowHTML' => true),
1681
        array('key' => 'activity', 'label' => $activity, 'sortable' => true, 'width' => '175px', 'allowHTML' => true),
1682
        array('key' => 'description', 'label' => $description, 'sortable' => true, 'width' => '250px', 'allowHTML' => true),
1683
        array('key' => 'preview', 'label' => $preview, 'width' => '250px', 'allowHTML' => true),
1684
        array('key' => 'date', 'label' => $date, 'sortable' => true, 'width' => '225px', 'allowHTML' => true),
1685
        array('key' => 'duration', 'label' => $duration, 'width' => '50px'),
1686
        );
1687
    if ($bbbsession['managerecordings']) {
1688
        array_push($recordingsbncolumns, array('key' => 'actionbar', 'label' => $actionbar, 'width' => '120px',
1689
            'allowHTML' => true));
1690
    }
1691
    return $recordingsbncolumns;
1692
}
1693
1694
/**
1695
 * Helper function builds the data used by the recording table.
1696
 *
1697
 * @param array $bbbsession
1698
 * @param array $recordings
1699
 * @param array $tools
1700
 *
1701
 * @return array
1702
 */
1703
function bigbluebuttonbn_get_recording_data($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1704
    $tabledata = array();
1705
    // Build table content.
1706 View Code Duplication
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1707
        // There are recordings for this meeting.
1708
        foreach ($recordings as $recording) {
1709
            $row = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1710
            if ($row != null) {
1711
                array_push($tabledata, $row);
1712
            }
1713
        }
1714
    }
1715
    return $tabledata;
1716
}
1717
1718
/**
1719
 * Helper function builds the recording table.
1720
 *
1721
 * @param array $bbbsession
1722
 * @param array $recordings
1723
 * @param array $tools
1724
 *
1725
 * @return object
1726
 */
1727
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1728
    // Set strings to show.
1729
    $recording = get_string('view_recording_recording', 'bigbluebuttonbn');
1730
    $description = get_string('view_recording_description', 'bigbluebuttonbn');
1731
    $date = get_string('view_recording_date', 'bigbluebuttonbn');
1732
    $duration = get_string('view_recording_duration', 'bigbluebuttonbn');
1733
    $actionbar = get_string('view_recording_actionbar', 'bigbluebuttonbn');
1734
    $playback = get_string('view_recording_playback', 'bigbluebuttonbn');
1735
    $preview = get_string('view_recording_preview', 'bigbluebuttonbn');
1736
    // Declare the table.
1737
    $table = new html_table();
1738
    $table->data = array();
1739
    // Initialize table headers.
1740
    $table->head = array($playback, $recording, $description, $preview, $date, $duration);
1741
    $table->align = array('left', 'left', 'left', 'left', 'left', 'center');
1742
    $table->size = array('', '', '', '', '', '');
1743
    if ($bbbsession['managerecordings']) {
1744
        $table->head[] = $actionbar;
1745
        $table->align[] = 'left';
1746
        $table->size[] = (count($tools) * 40) . 'px';
1747
    }
1748
    // Build table content.
1749 View Code Duplication
    if (isset($recordings) && !array_key_exists('messageKey', $recordings)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1750
        // There are recordings for this meeting.
1751
        foreach ($recordings as $recording) {
1752
            if ( !bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) ) {
1753
                continue;
1754
            }
1755
            bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $tools, $table);
1756
        }
1757
    }
1758
    return $table;
1759
}
1760
1761
/**
1762
 * Helper function builds the recording table row and insert into table.
1763
 *
1764
 * @param array $bbbsession
1765
 * @param array $recording
1766
 * @param array $tools
1767
 * @param object $table
1768
 *
1769
 * @return array
1770
 */
1771
function bigbluebuttonbn_get_recording_table_row($bbbsession, $recording, $tools, &$table) {
1772
    $rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools);
1773
    if ($rowdata == null) {
1774
        return;
1775
    }
1776
    $row = new html_table_row();
1777
    $row->id = 'recording-td-'.$recording['recordID'];
1778
    $row->attributes['data-imported'] = 'false';
1779
    $texthead = '';
1780
    $texttail = '';
1781
    if (isset($recording['imported'])) {
1782
        $row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn');
1783
        $row->attributes['data-imported'] = 'true';
1784
        $texthead = '<em>';
1785
        $texttail = '</em>';
1786
    }
1787
    $rowdata->date_formatted = str_replace(' ', '&nbsp;', $rowdata->date_formatted);
1788
    $row->cells = array(
1789
        $texthead . $rowdata->recording . $texttail,
1790
        $texthead . $rowdata->activity . $texttail, $texthead . $rowdata->description . $texttail,
1791
        $rowdata->preview, $texthead . $rowdata->date_formatted . $texttail,
1792
        $rowdata->duration_formatted
1793
      );
1794
    if ($bbbsession['managerecordings']) {
1795
        $row->cells[] = $rowdata->actionbar;
1796
    }
1797
    array_push($table->data, $row);
1798
}
1799
1800
/**
1801
 * Helper function evaluates if recording row should be included in the table.
1802
 *
1803
 * @param array $bbbsession
1804
 * @param array $recording
1805
 *
1806
 * @return boolean
1807
 */
1808
function bigbluebuttonbn_include_recording_table_row($bbbsession, $recording) {
1809
    if ( isset($recording['imported']) || !isset($bbbsession['group']) || $recording['meetingID'] == $bbbsession['meetingid'] ) {
1810
        return true;
1811
    }
1812
    return false;
1813
}
1814
1815
/**
1816
 * Helper function triggers a send notification when the recording is ready.
1817
 *
1818
 * @param object $bigbluebuttonbn
1819
 *
1820
 * @return void
1821
 */
1822
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) {
1823
    $sender = get_admin();
1824
    // Prepare message.
1825
    $messagetext = '<p>'.get_string('email_body_recording_ready_for', 'bigbluebuttonbn').
1826
        ' &quot;' . $bigbluebuttonbn->name . '&quot; '.
1827
        get_string('email_body_recording_ready_is_ready', 'bigbluebuttonbn').'.</p>';
1828
    $context = context_course::instance($bigbluebuttonbn->course);
1829
    \mod_bigbluebuttonbn\locallib\notifier::notification_send($context, $sender, $bigbluebuttonbn, $messagetext);
1830
}
1831
1832
/**
1833
 * Helper evaluates if the bigbluebutton server used belongs to blindsidenetworks domain.
1834
 *
1835
 * @return boolean
1836
 */
1837
function bigbluebuttonbn_is_bn_server() {
1838
    $parsedurl = parse_url(\mod_bigbluebuttonbn\locallib\config::get('server_url'));
1839
    if (!isset($parsedurl['host'])) {
1840
        return false;
1841
    }
1842
    $h = $parsedurl['host'];
1843
    $hends = explode('.', $h);
1844
    $hendslength = count($hends);
1845
    return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
1846
}
1847
1848
/**
1849
 * Helper function returns a list of courses a user has access to, wrapped in an array that can be used
1850
 * by a html select.
1851
 *
1852
 * @param array $bbbsession
1853
 *
1854
 * @return array
1855
 */
1856
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) {
1857
    if ($bbbsession['administrator']) {
1858
        $courses = get_courses('all', 'c.fullname ASC', 'c.id,c.shortname,c.fullname');
1859
        // It includes the name of the site as a course (category 0), so remove the first one.
1860
        unset($courses['1']);
1861
    } else {
1862
        $courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname');
1863
    }
1864
    $coursesforselect = [];
1865
    foreach ($courses as $course) {
1866
        $coursesforselect[$course->id] = $course->fullname;
1867
    }
1868
    return $coursesforselect;
1869
}
1870
1871
/**
1872
 * Helper function renders recording table.
1873
 *
1874
 * @param array $bbbsession
1875
 * @param array $recordings
1876
 * @param array $tools
1877
 *
1878
 * @return array
1879
 */
1880
function bigbluebuttonbn_output_recording_table($bbbsession, $recordings, $tools = ['protect', 'publish', 'delete']) {
1881
    if (isset($recordings) && !empty($recordings)) {
1882
        // There are recordings for this meeting.
1883
        $table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools);
1884
    }
1885
    if (!isset($table) || !isset($table->data)) {
1886
        // Render a table with "No recordings".
1887
        return html_writer::div(get_string('view_message_norecordings', 'bigbluebuttonbn'), '',
1888
            array('id' => 'bigbluebuttonbn_html_table'));
1889
    }
1890
    // Render the table.
1891
    return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_html_table'));
1892
}
1893
1894
/**
1895
 * Helper function to convert an html string to plain text.
1896
 *
1897
 * @param string $html
1898
 * @param integer $len
1899
 *
1900
 * @return string
1901
 */
1902
function bigbluebuttonbn_html2text($html, $len = 0) {
1903
    $text = strip_tags($html);
1904
    $text = str_replace('&nbsp;', ' ', $text);
1905
    $textlen = strlen($text);
1906
    $text = substr($text, 0, $len);
1907
    if ($textlen > $len) {
1908
        $text .= '...';
1909
    }
1910
    return $text;
1911
}
1912
1913
/**
1914
 * Helper function to obtain the tags linked to a bigbluebuttonbn activity
1915
 *
1916
 * @param string $id
1917
 *
1918
 * @return string containing the tags separated by commas
1919
 */
1920
function bigbluebuttonbn_get_tags($id) {
1921
    $tagsarray = core_tag_tag::get_item_tags_array('core', 'course_modules', $id);
1922
    return implode(',', $tagsarray);
1923
}
1924
1925
/**
1926
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1927
 * in the getRecordings request
1928
 *
1929
 * @param string $courseid
1930
 * @param string $bigbluebuttonbnid
1931
 * @param bool   $subset
1932
 *
1933
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1934
 */
1935
function bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid = null, $subset = true) {
1936
    if (empty($courseid)) {
1937
        $courseid = 0;
1938
    }
1939
    if ($bigbluebuttonbnid === null) {
1940
        return "course = '{$courseid}'";
1941
    }
1942
    if ($subset) {
1943
        return "id = '{$bigbluebuttonbnid}'";
1944
    }
1945
    return "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'";
1946
}
1947
1948
/**
1949
 * Helper function to define the sql used for gattering the bigbluebuttonbnids whose meetingids should be included
1950
 * in the getRecordings request considering only those that belong to deleted activities.
1951
 *
1952
 * @param string $courseid
1953
 * @param string $bigbluebuttonbnid
1954
 * @param bool   $subset
1955
 *
1956
 * @return string containing the sql used for getting the target bigbluebuttonbn instances
1957
 */
1958
function bigbluebuttonbn_get_recordings_sql_selectdeleted($courseid = 0, $bigbluebuttonbnid = null, $subset = true) {
1959
    $sql = "log = '" . BIGBLUEBUTTONBN_LOG_EVENT_DELETE . "' AND meta like '%has_recordings%' AND meta like '%true%'";
1960
    if (empty($courseid)) {
1961
        $courseid = 0;
1962
    }
1963
    if ($bigbluebuttonbnid === null) {
1964
        return $sql . " AND courseid = {$courseid}";
1965
    }
1966
    if ($subset) {
1967
        return $sql . " AND bigbluebuttonbnid = '{$bigbluebuttonbnid}'";
1968
    }
1969
    return $sql . " AND courseid = {$courseid} AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}'";
1970
}
1971
1972
/**
1973
 * Helper function to get recordings  and imported recordings together.
1974
 *
1975
 * @param string $courseid
1976
 * @param string $bigbluebuttonbnid
1977
 * @param bool   $subset
1978
 * @param bool   $includedeleted
1979
 *
1980
 * @return associative array containing the recordings indexed by recordID, each recording is also a
1981
 * non sequential associative array itself that corresponds to the actual recording in BBB
1982
 */
1983
function bigbluebuttonbn_get_allrecordings($courseid, $bigbluebuttonbnid = null, $subset = true,
1984
        $includedeleted = false) {
1985
        $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $subset, $includedeleted);
1986
        $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset);
1987
        return ($recordings + $recordingsimported);
1988
}
1989
1990
/**
1991
 * Helper function to retrieve recordings from the BigBlueButton. The references are stored as events
1992
 * in bigbluebuttonbn_logs.
1993
 *
1994
 * @param string $courseid
1995
 * @param string $bigbluebuttonbnid
1996
 * @param bool   $subset
1997
 * @param bool   $includedeleted
1998
 *
1999
 * @return associative array containing the recordings indexed by recordID, each recording is also a
2000
 * non sequential associative array itself that corresponds to the actual recording in BBB
2001
 */
2002
function bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid = null, $subset = true,
2003
        $includedeleted = false) {
2004
    global $DB;
2005
    $select = bigbluebuttonbn_get_recordings_sql_select($courseid, $bigbluebuttonbnid, $subset);
2006
    $bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid');
2007
    /* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in
2008
     * the getRecordings request. */
2009
    if ($includedeleted) {
2010
        $selectdeleted = bigbluebuttonbn_get_recordings_sql_selectdeleted($courseid, $bigbluebuttonbnid, $subset);
2011
        $bigbluebuttonbnsdel = $DB->get_records_select_menu('bigbluebuttonbn_logs', $selectdeleted, null,
2012
            'bigbluebuttonbnid', 'bigbluebuttonbnid, meetingid');
2013
        if (!empty($bigbluebuttonbnsdel)) {
2014
            // Merge bigbluebuttonbnis from deleted instances, only keys are relevant.
2015
            // Artimetic merge is used in order to keep the keys.
2016
            $bigbluebuttonbns += $bigbluebuttonbnsdel;
2017
        }
2018
    }
2019
    // Gather the meetingids from bigbluebuttonbn logs that include a create with record=true.
2020
    if (empty($bigbluebuttonbns)) {
2021
        return array();
2022
    }
2023
    // Prepare select for loading records based on existent bigbluebuttonbns.
2024
    $sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE ';
2025
    $sql .= '(bigbluebuttonbnid='.implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)).')';
2026
    // Include only Create events and exclude those with record not true.
2027
    $sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?';
2028
    // Execute select for loading records based on existent bigbluebuttonbns.
2029
    $records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%'));
2030
    // Get actual recordings.
2031
    return bigbluebuttonbn_get_recordings_array(array_keys($records));
2032
}
2033
2034
/**
2035
 * Helper function iterates an array with recordings and unset those already imported.
2036
 *
2037
 * @param array $recordings
2038
 * @param integer $courseid
2039
 * @param integer $bigbluebuttonbnid
2040
 *
2041
 * @return array
2042
 */
2043
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) {
2044
    $recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true);
2045
    foreach ($recordings as $key => $recording) {
2046
        if (isset($recordingsimported[$recording['recordID']])) {
2047
            unset($recordings[$key]);
2048
        }
2049
    }
2050
    return $recordings;
2051
}
2052
2053
/**
2054
 * Helper function to count the imported recordings for a recordingid.
2055
 *
2056
 * @param string $recordid
2057
 *
2058
 * @return integer
2059
 */
2060
function bigbluebuttonbn_get_count_recording_imported_instances($recordid) {
2061
    global $DB;
2062
    $sql = 'SELECT COUNT(DISTINCT id) FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2063
    return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%"));
2064
}
2065
2066
/**
2067
 * Helper function returns an array with all the instances of imported recordings for a recordingid.
2068
 *
2069
 * @param string $recordid
2070
 *
2071
 * @return array
2072
 */
2073
function bigbluebuttonbn_get_recording_imported_instances($recordid) {
2074
    global $DB;
2075
    $sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?';
2076
    $recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%',
2077
        "%{$recordid}%"));
2078
    return $recordingsimported;
2079
}
2080
2081
/**
2082
 * Helper function returns an array with the profiles (with features per profile) for the different types
2083
 * of bigbluebuttonbn instances.
2084
 *
2085
 * @return array
2086
 */
2087
function bigbluebuttonbn_get_instance_type_profiles() {
2088
    $instanceprofiles = array(
2089
            array('id' => BIGBLUEBUTTONBN_TYPE_ALL, 'name' => get_string('instance_type_default', 'bigbluebuttonbn'),
2090
                'features' => array('all')),
2091
            array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY, 'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'),
2092
                'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit', 'recording',
2093
                    'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups')),
2094
            array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY, 'name' => get_string('instance_type_recording_only',
2095
                'bigbluebuttonbn'), 'features' => array('showrecordings', 'importrecordings')),
2096
    );
2097
    return $instanceprofiles;
2098
}
2099
2100
/**
2101
 * Helper function returns an array with enabled features for an specific profile type.
2102
 *
2103
 * @param array $typeprofiles
2104
 * @param string $type
2105
 *
2106
 * @return array
2107
 */
2108
function bigbluebuttonbn_get_enabled_features($typeprofiles, $type = null) {
2109
    $enabledfeatures = array();
2110
    $features = $typeprofiles[0]['features'];
2111
    if (!is_null($type)) {
2112
        $features = $typeprofiles[$type]['features'];
2113
    }
2114
    $enabledfeatures['showroom'] = (in_array('all', $features) || in_array('showroom', $features));
2115
    // Evaluates if recordings are enabled for the Moodle site.
2116
    $enabledfeatures['showrecordings'] = (in_array('all', $features) || in_array('showrecordings', $features));
2117
    $enabledfeatures['importrecordings'] = (in_array('all', $features) || in_array('importrecordings', $features));
2118
    return $enabledfeatures;
2119
}
2120
2121
/**
2122
 * Helper function returns an array with the profiles (with features per profile) for the different types
2123
 * of bigbluebuttonbn instances.
2124
 *
2125
 * @param array $profiles
2126
 *
2127
 * @return array
2128
 */
2129
function bigbluebuttonbn_get_instance_profiles_array($profiles = null) {
2130
    if (is_null($profiles) || empty($profiles)) {
2131
        $profiles = bigbluebuttonbn_get_instance_type_profiles();
2132
    }
2133
    $profilesarray = array();
2134
    foreach ($profiles as $profile) {
2135
        $profilesarray += array("{$profile['id']}" => $profile['name']);
2136
    }
2137
    return $profilesarray;
2138
}
2139
2140
/**
2141
 * Helper function returns time in a formatted string.
2142
 *
2143
 * @param integer $time
2144
 *
2145
 * @return string
2146
 */
2147
function bigbluebuttonbn_format_activity_time($time) {
2148
    $activitytime = '';
2149
    if ($time) {
2150
        $activitytime = calendar_day_representation($time).' '.
2151
          get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn').' '.
2152
          calendar_time_representation($time);
2153
    }
2154
    return $activitytime;
2155
}
2156
2157
/**
2158
 * Helper function returns array with all the strings to be used in javascript.
2159
 *
2160
 * @return array
2161
 */
2162
function bigbluebuttonbn_get_strings_for_js() {
2163
    $locale = bigbluebuttonbn_get_locale();
2164
    $stringman = get_string_manager();
2165
    $strings = $stringman->load_component_strings('bigbluebuttonbn', $locale);
2166
    return $strings;
2167
}
2168
2169
/**
2170
 * Helper function returns the locale set by moodle.
2171
 *
2172
 * @return string
2173
 */
2174
function bigbluebuttonbn_get_locale() {
2175
    $lang = get_string('locale', 'core_langconfig');
2176
    return substr($lang, 0, strpos($lang, '.'));
2177
}
2178
2179
/**
2180
 * Helper function returns the locale code based on the locale set by moodle.
2181
 *
2182
 * @return string
2183
 */
2184
function bigbluebuttonbn_get_localcode() {
2185
    $locale = bigbluebuttonbn_get_locale();
2186
    return substr($locale, 0, strpos($locale, '_'));
2187
}
2188
2189
/**
2190
 * Helper function returns array with the instance settings used in views.
2191
 *
2192
 * @param string $id
2193
 * @param object $bigbluebuttonbnid
2194
 *
2195
 * @return array
2196
 */
2197
function bigbluebuttonbn_views_validator($id, $bigbluebuttonbnid) {
2198
    if ($id) {
2199
        return bigbluebuttonbn_views_instance_id($id);
2200
    }
2201
    if ($bigbluebuttonbnid) {
2202
        return bigbluebuttonbn_views_instance_bigbluebuttonbn($bigbluebuttonbnid);
2203
    }
2204
    return;
2205
}
2206
2207
/**
2208
 * Helper function returns array with the instance settings used in views based on id.
2209
 *
2210
 * @param string $id
2211
 *
2212
 * @return array
2213
 */
2214 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...
2215
    global $DB;
2216
    $cm = get_coursemodule_from_id('bigbluebuttonbn', $id, 0, false, MUST_EXIST);
2217
    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
2218
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance), '*', MUST_EXIST);
2219
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2220
}
2221
2222
/**
2223
 * Helper function returns array with the instance settings used in views based on bigbluebuttonbnid.
2224
 *
2225
 * @param object $bigbluebuttonbnid
2226
 *
2227
 * @return array
2228
 */
2229 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...
2230
    global $DB;
2231
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbnid), '*', MUST_EXIST);
2232
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
2233
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
2234
    return array('cm' => $cm, 'course' => $course, 'bigbluebuttonbn' => $bigbluebuttonbn);
2235
}
2236
2237
/**
2238
 * Helper function renders general settings if the feature is enabled.
2239
 *
2240
 * @param object $renderer
2241
 *
2242
 * @return void
2243
 */
2244
function bigbluebutonbn_settings_general(&$renderer) {
2245
    // Configuration for BigBlueButton.
2246
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_general_shown()) {
2247
        $renderer->render_group_header('general');
2248
        $renderer->render_group_element('server_url',
2249
            $renderer->render_group_element_text('server_url', BIGBLUEBUTTONBN_DEFAULT_SERVER_URL));
2250
        $renderer->render_group_element('shared_secret',
2251
            $renderer->render_group_element_text('shared_secret', BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET));
2252
    }
2253
}
2254
2255
/**
2256
 * Helper function renders record settings if the feature is enabled.
2257
 *
2258
 * @param object $renderer
2259
 *
2260
 * @return void
2261
 */
2262
function bigbluebutonbn_settings_record(&$renderer) {
2263
    // Configuration for 'recording' feature.
2264 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...
2265
        $renderer->render_group_header('recording');
2266
        $renderer->render_group_element('recording_default',
2267
            $renderer->render_group_element_checkbox('recording_default', 1));
2268
        $renderer->render_group_element('recording_editable',
2269
            $renderer->render_group_element_checkbox('recording_editable', 1));
2270
        $renderer->render_group_element('recording_icons_enabled',
2271
            $renderer->render_group_element_checkbox('recording_icons_enabled', 1));
2272
    }
2273
}
2274
2275
/**
2276
 * Helper function renders import recording settings if the feature is enabled.
2277
 *
2278
 * @param object $renderer
2279
 *
2280
 * @return void
2281
 */
2282 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...
2283
    // Configuration for 'import recordings' feature.
2284
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_import_recordings_shown()) {
2285
        $renderer->render_group_header('importrecordings');
2286
        $renderer->render_group_element('importrecordings_enabled',
2287
            $renderer->render_group_element_checkbox('importrecordings_enabled', 0));
2288
        $renderer->render_group_element('importrecordings_from_deleted_enabled',
2289
            $renderer->render_group_element_checkbox('importrecordings_from_deleted_enabled', 0));
2290
    }
2291
}
2292
2293
/**
2294
 * Helper function renders show recording settings if the feature is enabled.
2295
 *
2296
 * @param object $renderer
2297
 *
2298
 * @return void
2299
 */
2300
function bigbluebutonbn_settings_showrecordings(&$renderer) {
2301
    // Configuration for 'show recordings' feature.
2302
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_show_recordings_shown()) {
2303
        $renderer->render_group_header('recordings');
2304
        $renderer->render_group_element('recordings_html_default',
2305
            $renderer->render_group_element_checkbox('recordings_html_default', 1));
2306
        $renderer->render_group_element('recordings_html_editable',
2307
            $renderer->render_group_element_checkbox('recordings_html_editable', 0));
2308
        $renderer->render_group_element('recordings_deleted_default',
2309
            $renderer->render_group_element_checkbox('recordings_deleted_default', 1));
2310
        $renderer->render_group_element('recordings_deleted_editable',
2311
            $renderer->render_group_element_checkbox('recordings_deleted_editable', 0));
2312
        $renderer->render_group_element('recordings_imported_default',
2313
            $renderer->render_group_element_checkbox('recordings_imported_default', 0));
2314
        $renderer->render_group_element('recordings_imported_editable',
2315
            $renderer->render_group_element_checkbox('recordings_imported_editable', 1));
2316
    }
2317
}
2318
2319
/**
2320
 * Helper function renders wait for moderator settings if the feature is enabled.
2321
 *
2322
 * @param object $renderer
2323
 *
2324
 * @return void
2325
 */
2326
function bigbluebutonbn_settings_waitmoderator(&$renderer) {
2327
    // Configuration for wait for moderator feature.
2328
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_wait_moderator_shown()) {
2329
        $renderer->render_group_header('waitformoderator');
2330
        $renderer->render_group_element('waitformoderator_default',
2331
            $renderer->render_group_element_checkbox('waitformoderator_default', 0));
2332
        $renderer->render_group_element('waitformoderator_editable',
2333
            $renderer->render_group_element_checkbox('waitformoderator_editable', 1));
2334
        $renderer->render_group_element('waitformoderator_ping_interval',
2335
            $renderer->render_group_element_text('waitformoderator_ping_interval', 10, PARAM_INT));
2336
        $renderer->render_group_element('waitformoderator_cache_ttl',
2337
            $renderer->render_group_element_text('waitformoderator_cache_ttl', 60, PARAM_INT));
2338
    }
2339
}
2340
2341
/**
2342
 * Helper function renders static voice bridge settings if the feature is enabled.
2343
 *
2344
 * @param object $renderer
2345
 *
2346
 * @return void
2347
 */
2348
function bigbluebutonbn_settings_voicebridge(&$renderer) {
2349
    // Configuration for "static voice bridge" feature.
2350
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_static_voice_bridge_shown()) {
2351
        $renderer->render_group_header('voicebridge');
2352
        $renderer->render_group_element('voicebridge_editable',
2353
            $renderer->render_group_element_checkbox('voicebridge_editable', 0));
2354
    }
2355
}
2356
2357
/**
2358
 * Helper function renders preuploaded presentation settings if the feature is enabled.
2359
 *
2360
 * @param object $renderer
2361
 *
2362
 * @return void
2363
 */
2364
function bigbluebutonbn_settings_preupload(&$renderer) {
2365
    // Configuration for "preupload presentation" feature.
2366
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_preupload_presentation_shown()) {
2367
        // This feature only works if curl is installed.
2368
        $preuploaddescripion = get_string('config_preuploadpresentation_description', 'bigbluebuttonbn');
2369
        if (!extension_loaded('curl')) {
2370
            $preuploaddescripion .= '<div class="form-defaultinfo">';
2371
            $preuploaddescripion .= get_string('config_warning_curl_not_installed', 'bigbluebuttonbn');
2372
            $preuploaddescripion .= '</div><br>';
2373
        }
2374
        $renderer->render_group_header('preuploadpresentation', null, $preuploaddescripion);
2375
        if (extension_loaded('curl')) {
2376
            $renderer->render_group_element('preuploadpresentation_enabled',
2377
                $renderer->render_group_element_checkbox('preuploadpresentation_enabled', 0));
2378
        }
2379
    }
2380
}
2381
2382
/**
2383
 * Helper function renders userlimit settings if the feature is enabled.
2384
 *
2385
 * @param object $renderer
2386
 *
2387
 * @return void
2388
 */
2389
function bigbluebutonbn_settings_userlimit(&$renderer) {
2390
    // Configuration for "user limit" feature.
2391
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_user_limit_shown()) {
2392
        $renderer->render_group_header('userlimit');
2393
        $renderer->render_group_element('userlimit_default',
2394
            $renderer->render_group_element_text('userlimit_default', 0, PARAM_INT));
2395
        $renderer->render_group_element('userlimit_editable',
2396
            $renderer->render_group_element_checkbox('userlimit_editable', 0));
2397
    }
2398
}
2399
2400
/**
2401
 * Helper function renders duration settings if the feature is enabled.
2402
 *
2403
 * @param object $renderer
2404
 *
2405
 * @return void
2406
 */
2407
function bigbluebutonbn_settings_duration(&$renderer) {
2408
    // Configuration for "scheduled duration" feature.
2409 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...
2410
        $renderer->render_group_header('scheduled');
2411
        $renderer->render_group_element('scheduled_duration_enabled',
2412
            $renderer->render_group_element_checkbox('scheduled_duration_enabled', 1));
2413
        $renderer->render_group_element('scheduled_duration_compensation',
2414
            $renderer->render_group_element_text('scheduled_duration_compensation', 10, PARAM_INT));
2415
        $renderer->render_group_element('scheduled_pre_opening',
2416
            $renderer->render_group_element_text('scheduled_pre_opening', 10, PARAM_INT));
2417
    }
2418
}
2419
2420
/**
2421
 * Helper function renders participant settings if the feature is enabled.
2422
 *
2423
 * @param object $renderer
2424
 *
2425
 * @return void
2426
 */
2427
function bigbluebutonbn_settings_participants(&$renderer) {
2428
    // Configuration for defining the default role/user that will be moderator on new activities.
2429
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_moderator_default_shown()) {
2430
        $renderer->render_group_header('participant');
2431
        // UI for 'participants' feature.
2432
        $roles = bigbluebuttonbn_get_roles();
2433
        $owner = array('0' => get_string('mod_form_field_participant_list_type_owner', 'bigbluebuttonbn'));
2434
        $renderer->render_group_element('participant_moderator_default',
2435
            $renderer->render_group_element_configmultiselect('participant_moderator_default',
2436
                array_keys($owner), array_merge($owner, $roles))
2437
          );
2438
    }
2439
}
2440
2441
/**
2442
 * Helper function renders notification settings if the feature is enabled.
2443
 *
2444
 * @param object $renderer
2445
 *
2446
 * @return void
2447
 */
2448
function bigbluebutonbn_settings_notifications(&$renderer) {
2449
    // Configuration for "send notifications" feature.
2450
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_send_notifications_shown()) {
2451
        $renderer->render_group_header('sendnotifications');
2452
        $renderer->render_group_element('sendnotifications_enabled',
2453
            $renderer->render_group_element_checkbox('sendnotifications_enabled', 1));
2454
    }
2455
}
2456
2457
/**
2458
 * Helper function renders extended settings if any of the features there is enabled.
2459
 *
2460
 * @param object $renderer
2461
 *
2462
 * @return void
2463
 */
2464 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...
2465
    // Configuration for extended BN capabilities.
2466
    if (!bigbluebuttonbn_is_bn_server()) {
2467
        return;
2468
    }
2469
    // Configuration for 'notify users when recording ready' feature.
2470
    if ((boolean)\mod_bigbluebuttonbn\settings\renderer::section_settings_extended_shown()) {
2471
        $renderer->render_group_header('extended_capabilities');
2472
        // UI for 'notify users when recording ready' feature.
2473
        $renderer->render_group_element('recordingready_enabled',
2474
            $renderer->render_group_element_checkbox('recordingready_enabled', 0));
2475
        // UI for 'register meeting events' feature.
2476
        $renderer->render_group_element('meetingevents_enabled',
2477
            $renderer->render_group_element_checkbox('meetingevents_enabled', 0));
2478
    }
2479
}
2480
2481
/**
2482
 * Helper function returns an encoded meetingid.
2483
 *
2484
 * @param string $seed
2485
 *
2486
 * @return string
2487
 */
2488
function bigbluebuttonbn_encode_meetingid($seed) {
2489
    global $CFG;
2490
    return sha1($CFG->wwwroot . $seed . \mod_bigbluebuttonbn\locallib\config::get('shared_secret'));
2491
}
2492