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
|
|
|
* @author Fred Dixon (ffdixon [at] blindsidenetworks [dt] com) |
21
|
|
|
* @author Jesus Federico (jesus [at] blindsidenetworks [dt] com) |
22
|
|
|
* @copyright 2010-2017 Blindside Networks Inc |
23
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v2 or later |
24
|
|
|
*/ |
25
|
|
|
|
26
|
|
|
defined('MOODLE_INTERNAL') || die; |
27
|
|
|
|
28
|
|
|
global $CFG; |
29
|
|
|
|
30
|
|
|
require_once(dirname(__FILE__).'/lib.php'); |
31
|
|
|
|
32
|
|
|
const BIGBLUEBUTTONBN_FORCED = true; |
33
|
|
|
|
34
|
|
|
const BIGBLUEBUTTONBN_TYPE_ALL = 0; |
35
|
|
|
const BIGBLUEBUTTONBN_TYPE_ROOM_ONLY = 1; |
36
|
|
|
const BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY = 2; |
37
|
|
|
|
38
|
|
|
const BIGBLUEBUTTONBN_ROLE_VIEWER = 'viewer'; |
39
|
|
|
const BIGBLUEBUTTONBN_ROLE_MODERATOR = 'moderator'; |
40
|
|
|
const BIGBLUEBUTTONBN_METHOD_GET = 'GET'; |
41
|
|
|
const BIGBLUEBUTTONBN_METHOD_POST = 'POST'; |
42
|
|
|
|
43
|
|
|
const BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED = 'activity_viewed'; |
44
|
|
|
const BIGBLUEBUTTON_EVENT_MEETING_CREATED = 'meeting_created'; |
45
|
|
|
const BIGBLUEBUTTON_EVENT_MEETING_ENDED = 'meeting_ended'; |
46
|
|
|
const BIGBLUEBUTTON_EVENT_MEETING_JOINED = 'meeting_joined'; |
47
|
|
|
const BIGBLUEBUTTON_EVENT_MEETING_LEFT = 'meeting_left'; |
48
|
|
|
const BIGBLUEBUTTON_EVENT_MEETING_EVENT = 'meeting_event'; |
49
|
|
|
const BIGBLUEBUTTON_EVENT_RECORDING_DELETED = 'recording_deleted'; |
50
|
|
|
const BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED = 'recording_imported'; |
51
|
|
|
const BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED = 'recording_published'; |
52
|
|
|
const BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED = 'recording_unpublished'; |
53
|
|
|
|
54
|
|
|
function bigbluebuttonbn_logs(array $bbbsession, $event, array $overrides = [], $meta = null) { |
55
|
|
|
global $DB; |
56
|
|
|
|
57
|
|
|
$log = new stdClass(); |
58
|
|
|
|
59
|
|
|
// Default values. |
60
|
|
|
$log->courseid = $bbbsession['course']->id; |
61
|
|
|
$log->bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id; |
62
|
|
|
$log->userid = $bbbsession['userID']; |
63
|
|
|
$log->meetingid = $bbbsession['meetingid']; |
64
|
|
|
$log->timecreated = time(); |
65
|
|
|
// Overrides. |
66
|
|
|
foreach ($overrides as $key => $value) { |
67
|
|
|
$log->$key = $value; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
$log->log = $event; |
71
|
|
|
if (isset($meta)) { |
72
|
|
|
$log->meta = $meta; |
73
|
|
|
} else if ($event == BIGBLUEBUTTONBN_LOG_EVENT_CREATE) { |
74
|
|
|
$log->meta = '{"record":'.($bbbsession['record'] ? 'true' : 'false').'}'; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$DB->insert_record('bigbluebuttonbn_logs', $log); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
// BigBlueButton API Calls. |
81
|
|
|
function bigbluebuttonbn_get_join_url($meetingid, $username, $pw, $logouturl, $configtoken = null, $userid = null) { |
82
|
|
|
$data = ['meetingID' => $meetingid, |
83
|
|
|
'fullName' => $username, |
84
|
|
|
'password' => $pw, |
85
|
|
|
'logoutURL' => $logouturl, |
86
|
|
|
]; |
87
|
|
|
|
88
|
|
|
if (!is_null($configtoken)) { |
89
|
|
|
$data['configToken'] = $configtoken; |
90
|
|
|
} |
91
|
|
|
if (!is_null($userid)) { |
92
|
|
|
$data['userID'] = $userid; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
return bigbluebuttonbn_bigbluebutton_action_url('join', $data); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
function bigbluebuttonbn_get_create_meeting_url($name, $meetingid, $attendeepw, $moderatorpw, $welcome, |
99
|
|
|
$logouturl, $record = 'false', $duration = 0, $voicebridge = 0, $maxparticipants = 0, $metadata = array()) { |
100
|
|
|
$data = ['meetingID' => $meetingid, |
101
|
|
|
'name' => $name, |
102
|
|
|
'attendeePW' => $attendeepw, |
103
|
|
|
'moderatorPW' => $moderatorpw, |
104
|
|
|
'logoutURL' => $logouturl, |
105
|
|
|
'record' => $record, |
106
|
|
|
]; |
107
|
|
|
|
108
|
|
|
$voicebridge = intval($voicebridge); |
109
|
|
|
if ($voicebridge > 0 && $voicebridge < 79999) { |
110
|
|
|
$data['voiceBridge'] = $voicebridge; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
$duration = intval($duration); |
114
|
|
|
if ($duration > 0) { |
115
|
|
|
$data['duration'] = $duration; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
$maxparticipants = intval($maxparticipants); |
119
|
|
|
if ($maxparticipants > 0) { |
120
|
|
|
$data['maxParticipants'] = $maxparticipants; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
if (trim($welcome)) { |
124
|
|
|
$data['welcome'] = $welcome; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
return bigbluebuttonbn_bigbluebutton_action_url('create', $data, $metadata); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @param string $recordid |
132
|
|
|
* @param array $metadata |
133
|
|
|
*/ |
134
|
|
|
function bigbluebuttonbn_get_update_recordings_url($recordid, $metadata = array()) { |
135
|
|
|
return bigbluebuttonbn_bigbluebutton_action_url('updateRecordings', ['recordID' => $recordid], $metadata); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* @param string $action |
140
|
|
|
* @param array $data |
141
|
|
|
* @param array $metadata |
142
|
|
|
*/ |
143
|
|
|
function bigbluebuttonbn_bigbluebutton_action_url($action, $data = array(), $metadata = array()) { |
144
|
|
|
$baseurl = bigbluebuttonbn_get_cfg_server_url().'api/'.$action.'?'; |
145
|
|
|
|
146
|
|
|
$params = ''; |
147
|
|
|
|
148
|
|
|
foreach ($data as $key => $value) { |
149
|
|
|
$params .= '&'.$key.'='.urlencode($value); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
foreach ($metadata as $key => $value) { |
153
|
|
|
$params .= '&'.'meta_'.$key.'='.urlencode($value); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
return $baseurl.$params.'&checksum='.sha1($action.$params.bigbluebuttonbn_get_cfg_shared_secret()); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
function bigbluebuttonbn_get_create_meeting_array($meetingname, $meetingid, $welcomestring, $mpw, $apw, |
160
|
|
|
$logouturl, $record = 'false', $duration = 0, $voicebridge = 0, $maxparticipants = 0, |
161
|
|
|
$metadata = array(), $pname = null, $purl = null) { |
162
|
|
|
|
163
|
|
|
$createmeetingurl = bigbluebuttonbn_get_create_meeting_url($meetingname, $meetingid, $apw, $mpw, $welcomestring, |
164
|
|
|
$logouturl, $record, $duration, $voicebridge, $maxparticipants, $metadata); |
165
|
|
|
$method = BIGBLUEBUTTONBN_METHOD_GET; |
166
|
|
|
$data = null; |
167
|
|
|
|
168
|
|
|
if (!is_null($pname) && !is_null($purl)) { |
169
|
|
|
$method = BIGBLUEBUTTONBN_METHOD_POST; |
170
|
|
|
$data = "<?xml version='1.0' encoding='UTF-8'?><modules><module name='presentation'><document url='". |
171
|
|
|
$purl."' /></module></modules>"; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file($createmeetingurl, $method, $data); |
175
|
|
|
|
176
|
|
|
if ($xml) { |
177
|
|
|
$response = array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey); |
178
|
|
|
if ($xml->meetingID) { |
179
|
|
|
$response += array('meetingID' => $xml->meetingID, 'attendeePW' => $xml->attendeePW, |
180
|
|
|
'moderatorPW' => $xml->moderatorPW, 'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
return $response; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
return null; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* @param string $meetingid |
191
|
|
|
*/ |
192
|
|
|
function bigbluebuttonbn_get_meeting_array($meetingid) { |
193
|
|
|
$meetings = bigbluebuttonbn_get_meetings_array(); |
194
|
|
|
if ($meetings) { |
195
|
|
|
foreach ($meetings as $meeting) { |
196
|
|
|
if ($meeting['meetingID'] == $meetingid) { |
197
|
|
|
return $meeting; |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
return null; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
function bigbluebuttonbn_get_meetings_array() { |
206
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file(bigbluebuttonbn_bigbluebutton_action_url('getMeetings')); |
207
|
|
|
|
208
|
|
|
if ($xml && $xml->returncode == 'SUCCESS' && empty($xml->messageKey)) { |
209
|
|
|
// Meetings were returned. |
210
|
|
|
$meetings = array(); |
211
|
|
|
foreach ($xml->meetings->meeting as $meeting) { |
212
|
|
|
$meetings[] = array('meetingID' => $meeting->meetingID, |
213
|
|
|
'moderatorPW' => $meeting->moderatorPW, |
214
|
|
|
'attendeePW' => $meeting->attendeePW, |
215
|
|
|
'hasBeenForciblyEnded' => $meeting->hasBeenForciblyEnded, |
216
|
|
|
'running' => $meeting->running, ); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
return $meetings; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
View Code Duplication |
if ($xml) { |
|
|
|
|
223
|
|
|
// Either failutre or success without meetings. |
224
|
|
|
return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
// If the server is unreachable, then prompts the user of the necessary action. |
228
|
|
|
return null; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* @param string $meetingid |
233
|
|
|
*/ |
234
|
|
|
function bigbluebuttonbn_get_meeting_info_array($meetingid) { |
235
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
236
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('getMeetingInfo', ['meetingID' => $meetingid]) |
237
|
|
|
); |
238
|
|
|
|
239
|
|
|
if ($xml && $xml->returncode == 'SUCCESS' && empty($xml->messageKey)) { |
240
|
|
|
// Meeting info was returned. |
241
|
|
|
return array('returncode' => $xml->returncode, |
242
|
|
|
'meetingID' => $xml->meetingID, |
243
|
|
|
'moderatorPW' => $xml->moderatorPW, |
244
|
|
|
'attendeePW' => $xml->attendeePW, |
245
|
|
|
'hasBeenForciblyEnded' => $xml->hasBeenForciblyEnded, |
246
|
|
|
'running' => $xml->running, |
247
|
|
|
'recording' => $xml->recording, |
248
|
|
|
'startTime' => $xml->startTime, |
249
|
|
|
'endTime' => $xml->endTime, |
250
|
|
|
'participantCount' => $xml->participantCount, |
251
|
|
|
'moderatorCount' => $xml->moderatorCount, |
252
|
|
|
'attendees' => $xml->attendees, |
253
|
|
|
'metadata' => $xml->metadata, |
254
|
|
|
); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
View Code Duplication |
if ($xml) { |
|
|
|
|
258
|
|
|
// Either failutre or success without meeting info. |
259
|
|
|
return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
// If the server is unreachable, then prompts the user of the necessary action. |
263
|
|
|
return null; |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* helper function to retrieve recordings from a BigBlueButton server. |
268
|
|
|
* |
269
|
|
|
* @param string or array $meetingids list of meetingIDs "mid1,mid2,mid3" or array("mid1","mid2","mid3") |
270
|
|
|
* @param string or array $recordingids list of $recordingids "rid1,rid2,rid3" or array("rid1","rid2","rid3") for filtering |
271
|
|
|
* |
272
|
|
|
* @return associative array with recordings indexed by recordID, each recording is a non sequential associative array |
273
|
|
|
*/ |
274
|
|
|
function bigbluebuttonbn_get_recordings_array($meetingids, $recordingids = null) { |
275
|
|
|
$recordings = array(); |
276
|
|
|
|
277
|
|
|
$meetingidsarray = $meetingids; |
278
|
|
|
if (!is_array($meetingids)) { |
279
|
|
|
$meetingidsarray = explode(',', $meetingids); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
// If $meetingidsarray is not empty a paginated getRecordings request is executed. |
283
|
|
|
if (!empty($meetingidsarray)) { |
284
|
|
|
$pages = floor(count($meetingidsarray) / 25) + 1; |
285
|
|
|
for ($page = 1; $page <= $pages; ++$page) { |
286
|
|
|
$mids = array_slice($meetingidsarray, ($page - 1) * 25, 25); |
287
|
|
|
// Do getRecordings is executed using a method GET (supported by all versions of BBB). |
288
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
289
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('getRecordings', ['meetingID' => implode(',', $mids)]) |
290
|
|
|
); |
291
|
|
|
if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) { |
292
|
|
|
// If there were meetings already created. |
293
|
|
|
foreach ($xml->recordings->recording as $recording) { |
294
|
|
|
$recordingarrayvalue = bigbluebuttonbn_get_recording_array_value($recording); |
295
|
|
|
$recordings[$recordingarrayvalue['recordID']] = $recordingarrayvalue; |
296
|
|
|
} |
297
|
|
|
uasort($recordings, 'bigbluebuttonbn_recording_build_sorter'); |
298
|
|
|
} |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
// Filter recordings based on recordingIDs. |
303
|
|
|
if (!empty($recordings) && !is_null($recordingids)) { |
304
|
|
|
$recordingidsarray = $recordingids; |
305
|
|
|
if (!is_array($recordingids)) { |
306
|
|
|
$recordingidsarray = explode(',', $recordingids); |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
foreach ($recordings as $key => $recording) { |
310
|
|
|
if (!in_array($recording['recordID'], $recordingidsarray)) { |
311
|
|
|
unset($recordings[$key]); |
312
|
|
|
} |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
return $recordings; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* Helper function to retrieve imported recordings from the Moodle database. |
321
|
|
|
* The references are stored as events in bigbluebuttonbn_logs. |
322
|
|
|
* |
323
|
|
|
* @param string $courseid |
324
|
|
|
* @param string $bigbluebuttonbnid |
325
|
|
|
* @param bool $subset |
326
|
|
|
* |
327
|
|
|
* @return associative array with imported recordings indexed by recordID, each recording is a non sequential associative |
328
|
|
|
* array that corresponds to the actual recording in BBB |
329
|
|
|
*/ |
330
|
|
|
function bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid = null, $subset = true) { |
331
|
|
|
global $DB; |
332
|
|
|
|
333
|
|
|
$select = "courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}' AND log = '". |
334
|
|
|
BIGBLUEBUTTONBN_LOG_EVENT_IMPORT."'"; |
335
|
|
|
if ($bigbluebuttonbnid === null) { |
336
|
|
|
$select = "courseid = '{$courseid}' AND log = '".BIGBLUEBUTTONBN_LOG_EVENT_IMPORT."'"; |
337
|
|
|
} else if ($subset) { |
338
|
|
|
$select = "bigbluebuttonbnid = '{$bigbluebuttonbnid}' AND log = '".BIGBLUEBUTTONBN_LOG_EVENT_IMPORT."'"; |
339
|
|
|
} |
340
|
|
|
$recordsimported = $DB->get_records_select('bigbluebuttonbn_logs', $select); |
341
|
|
|
|
342
|
|
|
$recordingsimported = $recordsimported; |
343
|
|
|
// Check if array is not sequential. |
344
|
|
|
if (!empty($recordsimported) && array_keys($recordsimported) !== range(0, count($recordsimported) - 1)) { |
345
|
|
|
// The response contains a single record and needs to be converted to a sequential array format. |
346
|
|
|
$recordingsimported = array($recordsimported); |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
$recordsimportedarray = array(); |
350
|
|
|
foreach ($recordingsimported as $recordingimported) { |
351
|
|
|
$meta = json_decode($recordingimported->meta, true); |
352
|
|
|
$recordsimportedarray[$meta['recording']['recordID']] = $meta['recording']; |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
return $recordsimportedarray; |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
function bigbluebuttonbn_get_default_config_xml() { |
359
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
360
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('getDefaultConfigXML') |
361
|
|
|
); |
362
|
|
|
|
363
|
|
|
return $xml; |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
function bigbluebuttonbn_get_default_config_xml_array() { |
367
|
|
|
$defaultconfigxml = bigbluebuttonbn_getDefaultConfigXML(); |
368
|
|
|
|
369
|
|
|
return (array) $defaultconfigxml; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
function bigbluebuttonbn_get_recording_array_value($recording) { |
373
|
|
|
// Add formats. |
374
|
|
|
$playbackarray = array(); |
375
|
|
|
foreach ($recording->playback->format as $format) { |
376
|
|
|
$playbackarray[(string) $format->type] = array('type' => (string) $format->type, |
377
|
|
|
'url' => (string) $format->url, 'length' => (string) $format->length); |
378
|
|
|
// Add preview per format when existing. |
379
|
|
|
if ($format->preview) { |
380
|
|
|
$imagesarray = array(); |
381
|
|
|
foreach ($format->preview->images->image as $image) { |
382
|
|
|
$imagearray = array('url' => (string) $image); |
383
|
|
|
foreach ($image->attributes() as $attkey => $attvalue) { |
384
|
|
|
$imagearray[$attkey] = (string) $attvalue; |
385
|
|
|
} |
386
|
|
|
array_push($imagesarray, $imagearray); |
387
|
|
|
} |
388
|
|
|
$playbackarray[(string) $format->type]['preview'] = $imagesarray; |
389
|
|
|
} |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
// Add the metadata to the recordings array. |
393
|
|
|
$metadataarray = array(); |
394
|
|
|
$metadata = get_object_vars($recording->metadata); |
395
|
|
|
foreach ($metadata as $key => $value) { |
396
|
|
|
if (is_object($value)) { |
397
|
|
|
$value = ''; |
398
|
|
|
} |
399
|
|
|
$metadataarray['meta_'.$key] = $value; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
$recordingarrayvalue = array('recordID' => (string) $recording->recordID, |
403
|
|
|
'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name, |
404
|
|
|
'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime, |
405
|
|
|
'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray) + $metadataarray; |
406
|
|
|
|
407
|
|
|
return $recordingarrayvalue; |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
function bigbluebuttonbn_recording_build_sorter($a, $b) { |
411
|
|
|
if ($a['startTime'] < $b['startTime']) { |
412
|
|
|
return -1; |
413
|
|
|
} else if ($a['startTime'] == $b['startTime']) { |
414
|
|
|
return 0; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
return 1; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* @param string $recordids |
422
|
|
|
*/ |
423
|
|
View Code Duplication |
function bigbluebuttonbn_delete_recordings($recordids) { |
|
|
|
|
424
|
|
|
$ids = explode(',', $recordids); |
425
|
|
|
foreach ($ids as $id) { |
426
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
427
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('deleteRecordings', ['recordID' => $id]) |
428
|
|
|
); |
429
|
|
|
if ($xml && $xml->returncode != 'SUCCESS') { |
430
|
|
|
return false; |
431
|
|
|
} |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
return true; |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* @param string $recordids |
439
|
|
|
* @param string $publish |
440
|
|
|
*/ |
441
|
|
View Code Duplication |
function bigbluebuttonbn_publish_recordings($recordids, $publish = 'true') { |
|
|
|
|
442
|
|
|
$ids = explode(',', $recordids); |
443
|
|
|
foreach ($ids as $id) { |
444
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
445
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('publishRecordings', ['recordID' => $id, 'publish' => $publish]) |
446
|
|
|
); |
447
|
|
|
if ($xml && $xml->returncode != 'SUCCESS') { |
448
|
|
|
return false; |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
return true; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* @param string $meetingid |
457
|
|
|
* @param string $modpw |
458
|
|
|
*/ |
459
|
|
|
function bigbluebuttonbn_end_meeting($meetingid, $modpw) { |
460
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
461
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('end', ['meetingID' => $meetingid, 'password' => $modpw]) |
462
|
|
|
); |
463
|
|
|
|
464
|
|
View Code Duplication |
if ($xml) { |
|
|
|
|
465
|
|
|
// If the xml packet returned failure it displays the message to the user. |
466
|
|
|
return array('returncode' => $xml->returncode, 'message' => $xml->message, 'messageKey' => $xml->messageKey); |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
// If the server is unreachable, then prompts the user of the necessary action. |
470
|
|
|
return null; |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
/** |
474
|
|
|
* @param string $meetingid |
475
|
|
|
*/ |
476
|
|
|
function bigbluebuttonbn_is_meeting_running($meetingid) { |
477
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file( |
478
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('isMeetingRunning', ['meetingID' => $meetingid]) |
479
|
|
|
); |
480
|
|
|
|
481
|
|
|
if ($xml && $xml->returncode == 'SUCCESS') { |
482
|
|
|
return ($xml->running == 'true') ? true : false; |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
return false; |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
function bigbluebuttonbn_get_server_version() { |
489
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file(bigbluebuttonbn_get_cfg_server_url().'api'); |
490
|
|
|
|
491
|
|
|
if ($xml && $xml->returncode == 'SUCCESS') { |
492
|
|
|
return $xml->version; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
return null; |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
/** |
499
|
|
|
* @param string $url |
500
|
|
|
* @param string $data |
501
|
|
|
*/ |
502
|
|
|
function bigbluebuttonbn_wrap_xml_load_file($url, $method = BIGBLUEBUTTONBN_METHOD_GET, |
503
|
|
|
$data = null, $contenttype = 'text/xml') { |
504
|
|
|
|
505
|
|
|
debugging('Request to: '.$url, DEBUG_DEVELOPER); |
506
|
|
|
|
507
|
|
|
if (extension_loaded('curl')) { |
508
|
|
|
$response = bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method, $data, $contenttype); |
509
|
|
|
|
510
|
|
|
if (!$response) { |
511
|
|
|
debugging('No response on wrap_simplexml_load_file', DEBUG_DEVELOPER); |
512
|
|
|
return null; |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
debugging('Response: '.$response, DEBUG_DEVELOPER); |
516
|
|
|
|
517
|
|
|
$previous = libxml_use_internal_errors(true); |
518
|
|
|
try { |
519
|
|
|
$xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS); |
520
|
|
|
|
521
|
|
|
return $xml; |
522
|
|
|
} catch (Exception $e) { |
523
|
|
|
libxml_use_internal_errors($previous); |
524
|
|
|
$error = 'Caught exception: '.$e->getMessage(); |
525
|
|
|
debugging($error, DEBUG_DEVELOPER); |
526
|
|
|
return null; |
527
|
|
|
} |
528
|
|
|
} |
529
|
|
|
|
530
|
|
|
// Alternative request non CURL based. |
531
|
|
|
$previous = libxml_use_internal_errors(true); |
532
|
|
|
try { |
533
|
|
|
$response = simplexml_load_file($url, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS); |
534
|
|
|
debugging('Response processed: '.$response->asXML(), DEBUG_DEVELOPER); |
535
|
|
|
return $response; |
536
|
|
|
} catch (Exception $e) { |
537
|
|
|
$error = 'Caught exception: '.$e->getMessage(); |
538
|
|
|
debugging($error, DEBUG_DEVELOPER); |
539
|
|
|
libxml_use_internal_errors($previous); |
540
|
|
|
return null; |
541
|
|
|
} |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
function bigbluebuttonbn_wrap_xml_load_file_curl_request($url, $method = BIGBLUEBUTTONBN_METHOD_GET, |
545
|
|
|
$data = null, $contenttype = 'text/xml') { |
546
|
|
|
$c = new curl(); |
547
|
|
|
$c->setopt(array('SSL_VERIFYPEER' => true)); |
548
|
|
|
if ($method == BIGBLUEBUTTONBN_METHOD_POST) { |
549
|
|
|
if (is_null($data) || is_array($data)) { |
550
|
|
|
return $c->post($url); |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
$options = array(); |
554
|
|
|
$options['CURLOPT_HTTPHEADER'] = array( |
555
|
|
|
'Content-Type: '.$contenttype, |
556
|
|
|
'Content-Length: '.strlen($data), |
557
|
|
|
'Content-Language: en-US', |
558
|
|
|
); |
559
|
|
|
|
560
|
|
|
return $c->post($url, $data, $options); |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
return $c->get($url); |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
function bigbluebuttonbn_get_user_roles($context, $userid) { |
567
|
|
|
global $DB; |
568
|
|
|
|
569
|
|
|
$userroles = get_user_roles($context, $userid); |
570
|
|
|
if ($userroles) { |
571
|
|
|
$where = ''; |
572
|
|
|
foreach ($userroles as $value) { |
573
|
|
|
$where .= (empty($where) ? ' WHERE' : ' AND').' id='.$value->roleid; |
574
|
|
|
} |
575
|
|
|
$userroles = $DB->get_records_sql('SELECT * FROM {role}'.$where); |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
return $userroles; |
579
|
|
|
} |
580
|
|
|
|
581
|
|
|
function bigbluebuttonbn_get_guest_role() { |
582
|
|
|
$guestrole = get_guest_role(); |
583
|
|
|
|
584
|
|
|
return array($guestrole->id => $guestrole); |
585
|
|
|
} |
586
|
|
|
|
587
|
|
|
function bigbluebuttonbn_get_roles(context $context = null) { |
588
|
|
|
$roles = role_get_names($context); |
589
|
|
|
$rolesarray = array(); |
590
|
|
|
foreach ($roles as $role) { |
591
|
|
|
$rolesarray[$role->shortname] = $role->localname; |
592
|
|
|
} |
593
|
|
|
|
594
|
|
|
return $rolesarray; |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
function bigbluebuttonbn_get_roles_select($roles = array()) { |
598
|
|
|
$rolesarray = array(); |
599
|
|
|
foreach ($roles as $key => $value) { |
600
|
|
|
$rolesarray[] = array('id' => $key, 'name' => $value); |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
return $rolesarray; |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
function bigbluebuttonbn_get_users_select($users) { |
607
|
|
|
$usersarray = array(); |
608
|
|
|
foreach ($users as $user) { |
609
|
|
|
$usersarray[] = array('id' => $user->id, 'name' => fullname($user)); |
610
|
|
|
} |
611
|
|
|
|
612
|
|
|
return $usersarray; |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
function bigbluebuttonbn_get_participant_list($bigbluebuttonbn, $context = null) { |
616
|
|
|
if ($bigbluebuttonbn == null) { |
617
|
|
|
return bigbluebuttonbn_get_participant_list_default($context); |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
$participantlistarray = array(); |
621
|
|
|
$participantlist = json_decode($bigbluebuttonbn->participants); |
622
|
|
|
foreach ($participantlist as $participant) { |
623
|
|
|
$participantlistarray[] = array('selectiontype' => $participant->selectiontype, |
624
|
|
|
'selectionid' => $participant->selectionid, |
625
|
|
|
'role' => $participant->role, ); |
626
|
|
|
} |
627
|
|
|
|
628
|
|
|
return $participantlistarray; |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
function bigbluebuttonbn_get_participant_list_default($context) { |
632
|
|
|
global $USER; |
633
|
|
|
|
634
|
|
|
$participantlistarray = array(); |
635
|
|
|
$participantlistarray[] = array('selectiontype' => 'all', |
636
|
|
|
'selectionid' => 'all', |
637
|
|
|
'role' => BIGBLUEBUTTONBN_ROLE_VIEWER, ); |
638
|
|
|
|
639
|
|
|
$moderatordefaults = explode(',', bigbluebuttonbn_get_cfg_moderator_default()); |
640
|
|
|
foreach ($moderatordefaults as $moderatordefault) { |
641
|
|
|
if ($moderatordefault == 'owner') { |
642
|
|
|
$users = get_enrolled_users($context); |
643
|
|
|
foreach ($users as $user) { |
644
|
|
|
if ($user->id == $USER->id) { |
645
|
|
|
$participantlistarray[] = array('selectiontype' => 'user', |
646
|
|
|
'selectionid' => $USER->id, |
647
|
|
|
'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR, ); |
648
|
|
|
break; |
649
|
|
|
} |
650
|
|
|
} |
651
|
|
|
continue; |
652
|
|
|
} |
653
|
|
|
|
654
|
|
|
$participantlistarray[] = array('selectiontype' => 'role', |
655
|
|
|
'selectionid' => $moderatordefault, |
656
|
|
|
'role' => BIGBLUEBUTTONBN_ROLE_MODERATOR, ); |
657
|
|
|
} |
658
|
|
|
|
659
|
|
|
return $participantlistarray; |
660
|
|
|
} |
661
|
|
|
function bigbluebuttonbn_get_participant_list_json($bigbluebuttonbnid = null) { |
662
|
|
|
return json_encode(bigbluebuttonbn_get_participant_list($bigbluebuttonbnid)); |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
function bigbluebuttonbn_is_moderator($user, $roles, $participants) { |
666
|
|
|
$participantlist = json_decode($participants); |
667
|
|
|
|
668
|
|
|
// Iterate participant rules. |
669
|
|
|
foreach ($participantlist as $participant) { |
670
|
|
|
if ($participant->role == BIGBLUEBUTTONBN_ROLE_MODERATOR) { |
671
|
|
|
// Looks for all configuration. |
672
|
|
|
if ($participant->selectiontype == 'all') { |
673
|
|
|
return true; |
674
|
|
|
} |
675
|
|
|
// Looks for users. |
676
|
|
|
if ($participant->selectiontype == 'user' && $participant->selectionid == $user) { |
677
|
|
|
return true; |
678
|
|
|
} |
679
|
|
|
// Looks for roles. |
680
|
|
|
if ($participant->selectiontype == 'role') { |
681
|
|
|
foreach ($roles as $role) { |
682
|
|
|
if ($participant->selectionid == $role->shortname) { |
683
|
|
|
return true; |
684
|
|
|
} |
685
|
|
|
} |
686
|
|
|
} |
687
|
|
|
} |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
return false; |
691
|
|
|
} |
692
|
|
|
|
693
|
|
|
function bigbluebuttonbn_get_error_key($messagekey, $defaultkey = null) { |
694
|
|
|
$key = $defaultkey; |
695
|
|
|
if ($messagekey == 'checksumError') { |
696
|
|
|
$key = 'index_error_checksum'; |
697
|
|
|
} else if ($messagekey == 'maxConcurrent') { |
698
|
|
|
$key = 'view_error_max_concurrent'; |
699
|
|
|
} |
700
|
|
|
|
701
|
|
|
return $key; |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
function bigbluebuttonbn_voicebridge_unique($voicebridge, $id = null) { |
705
|
|
|
global $DB; |
706
|
|
|
|
707
|
|
|
$isunique = true; |
708
|
|
|
if ($voicebridge != 0) { |
709
|
|
|
$table = 'bigbluebuttonbn'; |
710
|
|
|
$select = 'voicebridge = '.$voicebridge; |
711
|
|
|
if ($id) { |
712
|
|
|
$select .= ' AND id <> '.$id; |
713
|
|
|
} |
714
|
|
|
if ($DB->get_records_select($table, $select)) { |
715
|
|
|
$isunique = false; |
716
|
|
|
} |
717
|
|
|
} |
718
|
|
|
|
719
|
|
|
return $isunique; |
720
|
|
|
} |
721
|
|
|
|
722
|
|
|
function bigbluebuttonbn_get_duration($closingtime) { |
723
|
|
|
$duration = 0; |
724
|
|
|
$now = time(); |
725
|
|
|
if ($closingtime > 0 && $now < $closingtime) { |
726
|
|
|
$duration = ceil(($closingtime - $now) / 60); |
727
|
|
|
$compensationtime = intval(bigbluebuttonbn_get_cfg_scheduled_duration_compensation()); |
728
|
|
|
$duration = intval($duration) + $compensationtime; |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
return $duration; |
732
|
|
|
} |
733
|
|
|
|
734
|
|
|
function bigbluebuttonbn_get_presentation_array($context, $presentation, $id = null) { |
735
|
|
|
$pname = null; |
736
|
|
|
$purl = null; |
737
|
|
|
$picon = null; |
738
|
|
|
$pmimetypedescrip = null; |
739
|
|
|
|
740
|
|
|
if (!empty($presentation)) { |
741
|
|
|
$fs = get_file_storage(); |
742
|
|
|
$files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0, |
743
|
|
|
'itemid, filepath, filename', false); |
744
|
|
|
if (count($files) >= 1) { |
745
|
|
|
$file = reset($files); |
746
|
|
|
unset($files); |
747
|
|
|
$pname = $file->get_filename(); |
748
|
|
|
$picon = file_file_icon($file, 24); |
749
|
|
|
$pmimetypedescrip = get_mimetype_description($file); |
750
|
|
|
$pnoncevalue = null; |
751
|
|
|
|
752
|
|
|
if (!is_null($id)) { |
753
|
|
|
// Create the nonce component for granting a temporary public access. |
754
|
|
|
$cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', |
755
|
|
|
'presentation_cache'); |
756
|
|
|
$pnoncekey = sha1($id); |
757
|
|
|
/* The item id was adapted for granting public access to the presentation once in order |
758
|
|
|
* to allow BigBlueButton to gather the file. */ |
759
|
|
|
$pnoncevalue = bigbluebuttonbn_generate_nonce(); |
760
|
|
|
$cache->set($pnoncekey, array('value' => $pnoncevalue, 'counter' => 0)); |
761
|
|
|
} |
762
|
|
|
$url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), |
763
|
|
|
$file->get_filearea(), $pnoncevalue, $file->get_filepath(), $file->get_filename()); |
764
|
|
|
|
765
|
|
|
$purl = $url->out(false); |
766
|
|
|
} |
767
|
|
|
} |
768
|
|
|
|
769
|
|
|
$parray = array('url' => $purl, 'name' => $pname, |
770
|
|
|
'icon' => $picon, |
771
|
|
|
'mimetype_description' => $pmimetypedescrip); |
772
|
|
|
|
773
|
|
|
return $parray; |
774
|
|
|
} |
775
|
|
|
|
776
|
|
|
function bigbluebuttonbn_generate_nonce() { |
777
|
|
|
$mt = microtime(); |
778
|
|
|
$rand = mt_rand(); |
779
|
|
|
|
780
|
|
|
return md5($mt.$rand); |
781
|
|
|
} |
782
|
|
|
|
783
|
|
|
function bigbluebuttonbn_random_password($length = 8) { |
784
|
|
|
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?'; |
785
|
|
|
$password = substr(str_shuffle($chars), 0, $length); |
786
|
|
|
|
787
|
|
|
return $password; |
788
|
|
|
} |
789
|
|
|
|
790
|
|
|
function bigbluebuttonbn_get_moodle_version_major() { |
791
|
|
|
global $CFG; |
792
|
|
|
|
793
|
|
|
$versionarray = explode('.', $CFG->version); |
794
|
|
|
|
795
|
|
|
return $versionarray[0]; |
796
|
|
|
} |
797
|
|
|
|
798
|
|
|
function bigbluebuttonbn_event_log_standard($eventtype, $bigbluebuttonbn, $cm, |
799
|
|
|
$timecreated = null, $userid = null, $eventsubtype = null) { |
800
|
|
|
|
801
|
|
|
$context = context_module::instance($cm->id); |
802
|
|
|
$eventproperties = array('context' => $context, 'objectid' => $bigbluebuttonbn->id); |
803
|
|
|
|
804
|
|
|
switch ($eventtype) { |
805
|
|
|
case BIGBLUEBUTTON_EVENT_MEETING_JOINED: |
806
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_meeting_joined::create($eventproperties); |
807
|
|
|
break; |
808
|
|
|
case BIGBLUEBUTTON_EVENT_MEETING_CREATED: |
809
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_meeting_created::create($eventproperties); |
810
|
|
|
break; |
811
|
|
|
case BIGBLUEBUTTON_EVENT_MEETING_ENDED: |
812
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_meeting_ended::create($eventproperties); |
813
|
|
|
break; |
814
|
|
|
case BIGBLUEBUTTON_EVENT_MEETING_LEFT: |
815
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_meeting_left::create($eventproperties); |
816
|
|
|
break; |
817
|
|
|
case BIGBLUEBUTTON_EVENT_RECORDING_PUBLISHED: |
818
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_recording_published::create($eventproperties); |
819
|
|
|
break; |
820
|
|
|
case BIGBLUEBUTTON_EVENT_RECORDING_UNPUBLISHED: |
821
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_recording_unpublished::create($eventproperties); |
822
|
|
|
break; |
823
|
|
|
case BIGBLUEBUTTON_EVENT_RECORDING_DELETED: |
824
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_recording_deleted::create($eventproperties); |
825
|
|
|
break; |
826
|
|
|
case BIGBLUEBUTTON_EVENT_ACTIVITY_VIEWED: |
827
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_activity_viewed::create($eventproperties); |
828
|
|
|
break; |
829
|
|
|
case BIGBLUEBUTTON_EVENT_ACTIVITY_MANAGEMENT_VIEWED: |
830
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_activity_management_viewed::create($eventproperties); |
831
|
|
|
break; |
832
|
|
|
case BIGBLUEBUTTON_EVENT_MEETING_EVENT: |
833
|
|
|
$eventproperties['userid'] = $userid; |
834
|
|
|
$eventproperties['timecreated'] = $timecreated; |
835
|
|
|
$eventproperties['other'] = $eventsubtype; |
836
|
|
|
$event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_meeting_event::create($eventproperties); |
837
|
|
|
break; |
838
|
|
|
} |
839
|
|
|
|
840
|
|
|
if (isset($event)) { |
841
|
|
|
$event->trigger(); |
842
|
|
|
} |
843
|
|
|
} |
844
|
|
|
|
845
|
|
|
function bigbluebuttonbn_event_log($eventtype, $bigbluebuttonbn, $cm) { |
846
|
|
|
bigbluebuttonbn_event_log_standard($eventtype, $bigbluebuttonbn, $cm); |
847
|
|
|
} |
848
|
|
|
|
849
|
|
|
function bigbluebuttonbn_meeting_event_log($event, $bigbluebuttonbn, $cm) { |
850
|
|
|
bigbluebuttonbn_event_log_standard(BIGBLUEBUTTON_EVENT_MEETING_EVENT, $bigbluebuttonbn, $cm, |
851
|
|
|
$event->timestamp, $event->user, $event->event); |
852
|
|
|
} |
853
|
|
|
|
854
|
|
|
/** |
855
|
|
|
* @param string $meetingid |
856
|
|
|
* @param bool $ismoderator |
857
|
|
|
*/ |
858
|
|
|
function bigbluebuttonbn_participant_joined($meetingid, $ismoderator) { |
859
|
|
|
$cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache'); |
860
|
|
|
$result = $cache->get($meetingid); |
861
|
|
|
$meetinginfo = json_decode($result['meeting_info']); |
862
|
|
|
$meetinginfo->participantCount += 1; |
863
|
|
|
if ($ismoderator) { |
864
|
|
|
$meetinginfo->moderatorCount += 1; |
865
|
|
|
} |
866
|
|
|
$cache->set($meetingid, array('creation_time' => $result['creation_time'], |
867
|
|
|
'meeting_info' => json_encode($meetinginfo))); |
868
|
|
|
} |
869
|
|
|
|
870
|
|
|
/** |
871
|
|
|
* @param string $meetingid |
872
|
|
|
* @param boolean $forced |
873
|
|
|
*/ |
874
|
|
|
function bigbluebuttonbn_get_meeting_info($meetingid, $forced = false) { |
875
|
|
|
$cachettl = bigbluebuttonbn_get_cfg_waitformoderator_cache_ttl(); |
876
|
|
|
|
877
|
|
|
$cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache'); |
878
|
|
|
$result = $cache->get($meetingid); |
879
|
|
|
$now = time(); |
880
|
|
|
if (!$forced && isset($result) && $now < ($result['creation_time'] + $cachettl)) { |
881
|
|
|
// Use the value in the cache. |
882
|
|
|
return json_decode($result['meeting_info']); |
883
|
|
|
} |
884
|
|
|
|
885
|
|
|
// Ping again and refresh the cache. |
886
|
|
|
$meetinginfo = (array) bigbluebuttonbn_wrap_xml_load_file( |
887
|
|
|
bigbluebuttonbn_bigbluebutton_action_url('getMeetingInfo', ['meetingID' => $meetingid]) |
888
|
|
|
); |
889
|
|
|
$cache->set($meetingid, array('creation_time' => time(), 'meeting_info' => json_encode($meetinginfo))); |
890
|
|
|
|
891
|
|
|
return $meetinginfo; |
892
|
|
|
} |
893
|
|
|
|
894
|
|
|
/** |
895
|
|
|
* @param string $recordingid |
896
|
|
|
* @param string $bigbluebuttonbnid |
897
|
|
|
* @param boolean $publish |
898
|
|
|
*/ |
899
|
|
|
function bigbluebuttonbn_publish_recording_imported($recordingid, $bigbluebuttonbnid, $publish = true) { |
900
|
|
|
global $DB; |
901
|
|
|
|
902
|
|
|
// Locate the record to be updated. |
903
|
|
|
$records = $DB->get_records('bigbluebuttonbn_logs', array('bigbluebuttonbnid' => $bigbluebuttonbnid, |
904
|
|
|
'log' => BIGBLUEBUTTONBN_LOG_EVENT_IMPORT)); |
905
|
|
|
|
906
|
|
|
foreach ($records as $key => $record) { |
907
|
|
|
$meta = json_decode($record->meta, true); |
908
|
|
|
if ($recordingid == $meta['recording']['recordID']) { |
909
|
|
|
// Found, prepare data for the update. |
910
|
|
|
$meta['recording']['published'] = ($publish) ? 'true' : 'false'; |
911
|
|
|
$records[$key]->meta = json_encode($meta); |
912
|
|
|
|
913
|
|
|
// Proceed with the update. |
914
|
|
|
$DB->update_record('bigbluebuttonbn_logs', $records[$key]); |
915
|
|
|
} |
916
|
|
|
} |
917
|
|
|
} |
918
|
|
|
|
919
|
|
|
function bigbluebuttonbn_delete_recording_imported($recordingid, $bigbluebuttonbnid) { |
920
|
|
|
global $DB; |
921
|
|
|
|
922
|
|
|
// Locate the record to be updated. |
923
|
|
|
$records = $DB->get_records('bigbluebuttonbn_logs', array('bigbluebuttonbnid' => $bigbluebuttonbnid, |
924
|
|
|
'log' => BIGBLUEBUTTONBN_LOG_EVENT_IMPORT)); |
925
|
|
|
|
926
|
|
|
foreach ($records as $key => $record) { |
927
|
|
|
$meta = json_decode($record->meta, true); |
928
|
|
|
if ($recordingid == $meta['recording']['recordID']) { |
929
|
|
|
// Execute delete. |
930
|
|
|
$DB->delete_records('bigbluebuttonbn_logs', array('id' => $key)); |
931
|
|
|
} |
932
|
|
|
} |
933
|
|
|
} |
934
|
|
|
|
935
|
|
|
function bigbluebuttonbn_validate_parameters($params) { |
936
|
|
|
$error = ''; |
937
|
|
|
|
938
|
|
|
if (!isset($params['callback'])) { |
939
|
|
|
return bigbluebuttonbn_add_error($error, 'This call must include a javascript callback.'); |
940
|
|
|
} |
941
|
|
|
|
942
|
|
|
if (!isset($params['action'])) { |
943
|
|
|
return bigbluebuttonbn_add_error($error, 'Action parameter must be included.'); |
944
|
|
|
} |
945
|
|
|
|
946
|
|
|
switch (strtolower($params['action'])) { |
947
|
|
|
case 'server_ping': |
948
|
|
|
case 'meeting_info': |
949
|
|
|
case 'meeting_end': |
950
|
|
|
if (!isset($params['id'])) { |
951
|
|
|
return bigbluebuttonbn_add_error($error, 'The meetingID must be specified.'); |
952
|
|
|
} |
953
|
|
|
break; |
954
|
|
|
case 'recording_info': |
955
|
|
|
case 'recording_links': |
956
|
|
|
case 'recording_publish': |
957
|
|
|
case 'recording_unpublish': |
958
|
|
|
case 'recording_delete': |
959
|
|
|
case 'recording_import': |
960
|
|
|
if (!isset($params['id'])) { |
961
|
|
|
return bigbluebuttonbn_add_error($error, 'The recordingID must be specified.'); |
962
|
|
|
} |
963
|
|
|
break; |
964
|
|
|
case 'recording_ready': |
965
|
|
|
case 'meeting_events': |
966
|
|
|
if (empty($params['signed_parameters'])) { |
967
|
|
|
return bigbluebuttonbn_add_error($error, 'A JWT encoded string must be included as [signed_parameters].'); |
968
|
|
|
} |
969
|
|
|
break; |
970
|
|
|
case 'moodle_event': |
971
|
|
|
break; |
972
|
|
|
default: |
973
|
|
|
return bigbluebuttonbn_add_error($error, 'Action '.$params['action'].' can not be performed.'); |
974
|
|
|
} |
975
|
|
|
|
976
|
|
|
return ''; |
977
|
|
|
} |
978
|
|
|
|
979
|
|
|
function bigbluebuttonbn_add_error($oldmsg, $newmsg = '') { |
980
|
|
|
$error = $oldmsg; |
981
|
|
|
|
982
|
|
|
if (!empty($newmsg)) { |
983
|
|
|
if (!empty($error)) { |
984
|
|
|
$error .= ' '; |
985
|
|
|
} |
986
|
|
|
$error .= $newmsg; |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
return $error; |
990
|
|
|
} |
991
|
|
|
|
992
|
|
|
/** |
993
|
|
|
* @param string $meetingid |
994
|
|
|
* @param string $configxml |
995
|
|
|
*/ |
996
|
|
|
function bigbluebuttonbn_set_config_xml_params($meetingid, $configxml) { |
997
|
|
|
$params = 'configXML='.urlencode($configxml).'&meetingID='.urlencode($meetingid); |
998
|
|
|
$configxmlparams = $params.'&checksum='.sha1('setConfigXML'.$params.bigbluebuttonbn_get_cfg_shared_secret()); |
999
|
|
|
|
1000
|
|
|
return $configxmlparams; |
1001
|
|
|
} |
1002
|
|
|
|
1003
|
|
|
/** |
1004
|
|
|
* @param string $meetingid |
1005
|
|
|
* @param string $configxml |
1006
|
|
|
*/ |
1007
|
|
|
function bigbluebuttonbn_set_config_xml($meetingid, $configxml) { |
1008
|
|
|
$urldefaultconfig = bigbluebuttonbn_get_cfg_server_url().'api/setConfigXML?'; |
1009
|
|
|
$configxmlparams = bigbluebuttonbn_set_config_xml_params($meetingid, $configxml); |
1010
|
|
|
$xml = bigbluebuttonbn_wrap_xml_load_file($urldefaultconfig, BIGBLUEBUTTONBN_METHOD_POST, |
1011
|
|
|
$configxmlparams, 'application/x-www-form-urlencoded'); |
1012
|
|
|
|
1013
|
|
|
return $xml; |
1014
|
|
|
} |
1015
|
|
|
|
1016
|
|
|
/** |
1017
|
|
|
* @param string $meetingid |
1018
|
|
|
* @param string $configxml |
1019
|
|
|
*/ |
1020
|
|
|
function bigbluebuttonbn_set_config_xml_array($meetingid, $configxml) { |
1021
|
|
|
$configxml = bigbluebuttonbn_setConfigXML($meetingid, $configxml); |
1022
|
|
|
$configxmlarray = (array) $configxml; |
1023
|
|
|
if ($configxmlarray['returncode'] != 'SUCCESS') { |
1024
|
|
|
debugging('BigBlueButton was not able to set the custom config.xml file', DEBUG_DEVELOPER); |
1025
|
|
|
return ''; |
1026
|
|
|
} |
1027
|
|
|
|
1028
|
|
|
return $configxmlarray['configToken']; |
1029
|
|
|
} |
1030
|
|
|
|
1031
|
|
|
function bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools = ['publishing', 'deleting']) { |
1032
|
|
|
global $USER; |
1033
|
|
|
|
1034
|
|
|
$row = null; |
1035
|
|
|
|
1036
|
|
|
if ($bbbsession['managerecordings'] || $recording['published'] == 'true') { |
1037
|
|
|
$row = new stdClass(); |
1038
|
|
|
|
1039
|
|
|
// Set recording_types. |
1040
|
|
|
$row->recording = bigbluebuttonbn_get_recording_data_row_types($recording); |
1041
|
|
|
|
1042
|
|
|
// Set activity name and description. |
1043
|
|
|
$row->activity = bigbluebuttonbn_get_recording_data_row_meta_activity(recording); |
1044
|
|
|
$row->description = bigbluebuttonbn_get_recording_data_row_meta_description(recording); |
1045
|
|
|
|
1046
|
|
|
// Set recording_preview. |
1047
|
|
|
$row->preview = bigbluebuttonbn_get_recording_data_row_preview($recording); |
1048
|
|
|
|
1049
|
|
|
// Set date. |
1050
|
|
|
$starttime = isset($recording['startTime']) ? floatval($recording['startTime']) : 0; |
1051
|
|
|
$starttime = $starttime - ($starttime % 1000); |
1052
|
|
|
$row->date = floatval($recording['startTime']); |
1053
|
|
|
|
1054
|
|
|
// Set formatted date. |
1055
|
|
|
$dateformat = get_string('strftimerecentfull', 'langconfig').' %Z'; |
1056
|
|
|
$row->date_formatted = userdate($starttime / 1000, $dateformat, usertimezone($USER->timezone)); |
1057
|
|
|
|
1058
|
|
|
// Set formatted duration. |
1059
|
|
|
$firstplayback = array_values($recording['playbacks'])[0]; |
1060
|
|
|
$length = isset($firstplayback['length']) ? $firstplayback['length'] : 0; |
1061
|
|
|
$row->duration_formatted = $row->duration = intval($length); |
1062
|
|
|
|
1063
|
|
|
// Set actionbar, if user is allowed to manage recordings. |
1064
|
|
|
if ($bbbsession['managerecordings']) { |
1065
|
|
|
$row->actionbar = bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools); |
1066
|
|
|
} |
1067
|
|
|
} |
1068
|
|
|
|
1069
|
|
|
return $row; |
1070
|
|
|
} |
1071
|
|
|
|
1072
|
|
|
function bigbluebuttonbn_get_recording_data_row_actionbar($recording, $tools) { |
1073
|
|
|
$actionbar = ''; |
1074
|
|
|
|
1075
|
|
|
if (in_array('publishing', $tools)) { |
1076
|
|
|
// Set action [show|hide]. |
1077
|
|
|
$manageaction = 'publish'; |
1078
|
|
|
$managetag = 'show'; |
1079
|
|
|
if ($recording['published'] == 'true') { |
1080
|
|
|
$manageaction = 'unpublish'; |
1081
|
|
|
$managetag = 'hide'; |
1082
|
|
|
} |
1083
|
|
|
$actionbar .= bigbluebuttonbn_actionbar_render($manageaction, $managetag, $recording); |
1084
|
|
|
} |
1085
|
|
|
|
1086
|
|
View Code Duplication |
if (in_array('deleting', $tools)) { |
|
|
|
|
1087
|
|
|
$manageaction = $managetag = 'delete'; |
1088
|
|
|
$actionbar .= bigbluebuttonbn_actionbar_render($manageaction, $managetag, $recording); |
1089
|
|
|
} |
1090
|
|
|
|
1091
|
|
View Code Duplication |
if (in_array('importing', $tools)) { |
|
|
|
|
1092
|
|
|
$manageaction = $managetag = 'import'; |
1093
|
|
|
$actionbar .= bigbluebuttonbn_actionbar_render($manageaction, $managetag, $recording); |
1094
|
|
|
} |
1095
|
|
|
|
1096
|
|
|
return $actionbar; |
1097
|
|
|
} |
1098
|
|
|
|
1099
|
|
|
function bigbluebuttonbn_get_recording_data_row_preview($recording) { |
1100
|
|
|
$recordingpreview = ''; |
1101
|
|
|
foreach ($recording['playbacks'] as $playback) { |
1102
|
|
|
if (isset($playback['preview'])) { |
1103
|
|
|
foreach ($playback['preview'] as $image) { |
1104
|
|
|
$recordingpreview .= html_writer::empty_tag('img', |
1105
|
|
|
array('src' => $image['url'], 'class' => 'thumbnail')); |
1106
|
|
|
} |
1107
|
|
|
$recordingpreview .= html_writer::empty_tag('br'); |
1108
|
|
|
$recordingpreview .= html_writer::tag('div', |
1109
|
|
|
get_string('view_recording_preview_help', 'bigbluebuttonbn'), array('class' => 'text-muted small')); |
1110
|
|
|
break; |
1111
|
|
|
} |
1112
|
|
|
} |
1113
|
|
|
|
1114
|
|
|
return $recordingpreview; |
1115
|
|
|
} |
1116
|
|
|
|
1117
|
|
|
function bigbluebuttonbn_get_recording_data_row_types($recording) { |
1118
|
|
|
global $OUTPUT; |
1119
|
|
|
|
1120
|
|
|
$attributes = 'data-imported="false"'; |
1121
|
|
|
if (isset($recording['imported'])) { |
1122
|
|
|
$attributes = 'data-imported="true" title="'.get_string('view_recording_link_warning', 'bigbluebuttonbn').'"'; |
1123
|
|
|
} |
1124
|
|
|
|
1125
|
|
|
$visibility = ''; |
1126
|
|
|
if ($recording['published'] === 'false') { |
1127
|
|
|
$visibility = 'hidden '; |
1128
|
|
|
} |
1129
|
|
|
|
1130
|
|
|
$recordingtypes = '<div id="playbacks-'.$recording['recordID'].'" '.$attributes.' '.$visibility.'>'; |
1131
|
|
|
foreach ($recording['playbacks'] as $playback) { |
1132
|
|
|
$recordingtypes .= $OUTPUT->action_link($playback['url'], get_string('view_recording_format_'.$playback['type'], |
1133
|
|
|
'bigbluebuttonbn'), null, array('title' => get_string('view_recording_format_'.$playback['type'], |
1134
|
|
|
'bigbluebuttonbn'), 'target' => '_new')).' '; |
1135
|
|
|
} |
1136
|
|
|
$recordingtypes .= '</div>'; |
1137
|
|
|
|
1138
|
|
|
return $recordingtypes; |
1139
|
|
|
} |
1140
|
|
|
|
1141
|
|
|
function bigbluebuttonbn_get_recording_data_row_meta_activity($recording) { |
1142
|
|
|
if (isset($recording['meta_contextactivity'])) { |
1143
|
|
|
return htmlentities($recording['meta_contextactivity']); |
1144
|
|
|
} else if (isset($recording['meta_bbb-recording-name'])) { |
1145
|
|
|
return htmlentities($recording['meta_bbb-recording-name']); |
1146
|
|
|
} |
1147
|
|
|
|
1148
|
|
|
return htmlentities($recording['meetingName']); |
1149
|
|
|
} |
1150
|
|
|
|
1151
|
|
|
function bigbluebuttonbn_get_recording_data_row_meta_description($recording) { |
1152
|
|
|
$metadescription = html_writer::start_tag('div', array('class' => 'col-md-20')); |
1153
|
|
|
if (isset($recording['meta_contextactivitydescription']) && |
1154
|
|
|
trim($recording['meta_contextactivitydescription']) != '') { |
1155
|
|
|
$metadescription .= htmlentities($recording['meta_contextactivitydescription']); |
1156
|
|
|
} else if (isset($recording['meta_bbb-recording-description']) && |
1157
|
|
|
trim($recording['meta_bbb-recording-description']) != '') { |
1158
|
|
|
$metadescription .= htmlentities($recording['meta_bbb-recording-description']); |
1159
|
|
|
} |
1160
|
|
|
$metadescription .= html_writer::end_tag('div'); |
1161
|
|
|
|
1162
|
|
|
return $metadescription; |
1163
|
|
|
} |
1164
|
|
|
|
1165
|
|
|
function bigbluebuttonbn_actionbar_render($manageaction, $managetag, $recording) { |
1166
|
|
|
global $OUTPUT; |
1167
|
|
|
|
1168
|
|
|
$onclick = 'M.mod_bigbluebuttonbn.broker_manageRecording("'.$manageaction.'", "'. |
1169
|
|
|
$recording['recordID'].'", "'.$recording['meetingID'].'");'; |
1170
|
|
|
if (bigbluebuttonbn_get_cfg_recording_icons_enabled()) { |
1171
|
|
|
// With icon for $manageaction. |
1172
|
|
|
$iconattributes = array('id' => 'recording-btn-'.$manageaction.'-'.$recording['recordID']); |
1173
|
|
|
$icon = new pix_icon('i/'.$managetag, get_string($managetag), 'moodle', $iconattributes); |
1174
|
|
|
$linkattributes = array('id' => 'recording-link-'.$manageaction.'-'.$recording['recordID'], |
1175
|
|
|
'onclick' => $onclick); |
1176
|
|
|
|
1177
|
|
|
return $OUTPUT->action_icon('#', $icon, null, $linkattributes, false); |
1178
|
|
|
} |
1179
|
|
|
|
1180
|
|
|
// With text for $manageaction. |
1181
|
|
|
$linkattributes = array('title' => get_string($managetag), 'class' => 'btn btn-xs btn-danger', |
1182
|
|
|
'onclick' => $onclick); |
1183
|
|
|
|
1184
|
|
|
return $OUTPUT->action_link('#', get_string($manageaction), null, $linkattributes); |
1185
|
|
|
} |
1186
|
|
|
|
1187
|
|
|
function bigbluebuttonbn_get_recording_columns($bbbsession) { |
1188
|
|
|
// Set strings to show. |
1189
|
|
|
$recording = get_string('view_recording_recording', 'bigbluebuttonbn'); |
1190
|
|
|
$activity = get_string('view_recording_activity', 'bigbluebuttonbn'); |
1191
|
|
|
$description = get_string('view_recording_description', 'bigbluebuttonbn'); |
1192
|
|
|
$preview = get_string('view_recording_preview', 'bigbluebuttonbn'); |
1193
|
|
|
$date = get_string('view_recording_date', 'bigbluebuttonbn'); |
1194
|
|
|
$duration = get_string('view_recording_duration', 'bigbluebuttonbn'); |
1195
|
|
|
$actionbar = get_string('view_recording_actionbar', 'bigbluebuttonbn'); |
1196
|
|
|
|
1197
|
|
|
// Initialize table headers. |
1198
|
|
|
$recordingsbncolumns = array( |
1199
|
|
|
array('key' => 'recording', 'label' => $recording, 'width' => '125px', 'allowHTML' => true), |
1200
|
|
|
array('key' => 'activity', 'label' => $activity, 'sortable' => true, 'width' => '175px', 'allowHTML' => true), |
1201
|
|
|
array('key' => 'description', 'label' => $description, 'width' => '250px', 'sortable' => true, |
1202
|
|
|
'width' => '250px', 'allowHTML' => true), |
1203
|
|
|
array('key' => 'preview', 'label' => $preview, 'width' => '250px', 'allowHTML' => true), |
1204
|
|
|
array('key' => 'date', 'label' => $date, 'sortable' => true, 'width' => '225px', 'allowHTML' => true), |
1205
|
|
|
array('key' => 'duration', 'label' => $duration, 'width' => '50px'), |
1206
|
|
|
); |
1207
|
|
|
|
1208
|
|
|
if ($bbbsession['managerecordings']) { |
1209
|
|
|
array_push($recordingsbncolumns, array('key' => 'actionbar', 'label' => $actionbar, 'width' => '100px', |
1210
|
|
|
'allowHTML' => true)); |
1211
|
|
|
} |
1212
|
|
|
|
1213
|
|
|
return $recordingsbncolumns; |
1214
|
|
|
} |
1215
|
|
|
|
1216
|
|
|
function bigbluebuttonbn_get_recording_data($bbbsession, $recordings, $tools = ['publishing', 'deleting']) { |
1217
|
|
|
$tabledata = array(); |
1218
|
|
|
|
1219
|
|
|
// Build table content. |
1220
|
|
|
if (isset($recordings) && !array_key_exists('messageKey', $recordings)) { |
1221
|
|
|
// There are recordings for this meeting. |
1222
|
|
|
foreach ($recordings as $recording) { |
1223
|
|
|
$row = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools); |
1224
|
|
|
if ($row != null) { |
1225
|
|
|
array_push($tabledata, $row); |
1226
|
|
|
} |
1227
|
|
|
} |
1228
|
|
|
} |
1229
|
|
|
|
1230
|
|
|
return $tabledata; |
1231
|
|
|
} |
1232
|
|
|
|
1233
|
|
|
function bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools = ['publishing', 'deleting']) { |
1234
|
|
|
// Set strings to show. |
1235
|
|
|
$recording = get_string('view_recording_recording', 'bigbluebuttonbn'); |
1236
|
|
|
$description = get_string('view_recording_description', 'bigbluebuttonbn'); |
1237
|
|
|
$date = get_string('view_recording_date', 'bigbluebuttonbn'); |
1238
|
|
|
$duration = get_string('view_recording_duration', 'bigbluebuttonbn'); |
1239
|
|
|
$actionbar = get_string('view_recording_actionbar', 'bigbluebuttonbn'); |
1240
|
|
|
$playback = get_string('view_recording_playback', 'bigbluebuttonbn'); |
1241
|
|
|
$preview = get_string('view_recording_preview', 'bigbluebuttonbn'); |
1242
|
|
|
|
1243
|
|
|
// Declare the table. |
1244
|
|
|
$table = new html_table(); |
1245
|
|
|
$table->data = array(); |
1246
|
|
|
|
1247
|
|
|
// Initialize table headers. |
1248
|
|
|
$table->head = array($playback.$recording, $description, $preview, $date, $duration); |
1249
|
|
|
$table->align = array('left', 'left', 'left', 'left', 'left', 'center'); |
1250
|
|
|
if ($bbbsession['managerecordings']) { |
1251
|
|
|
$table->head[] = $actionbar; |
1252
|
|
|
$table->align[] = 'left'; |
1253
|
|
|
} |
1254
|
|
|
|
1255
|
|
|
// Build table content. |
1256
|
|
|
if (isset($recordings) && !array_key_exists('messageKey', $recordings)) { |
1257
|
|
|
// There are recordings for this meeting. |
1258
|
|
|
foreach ($recordings as $recording) { |
1259
|
|
|
$row = new html_table_row(); |
1260
|
|
|
$row->id = 'recording-td-'.$recording['recordID']; |
1261
|
|
|
$row->attributes['data-imported'] = 'false'; |
1262
|
|
|
if (isset($recording['imported'])) { |
1263
|
|
|
$row->attributes['data-imported'] = 'true'; |
1264
|
|
|
$row->attributes['title'] = get_string('view_recording_link_warning', 'bigbluebuttonbn'); |
1265
|
|
|
} |
1266
|
|
|
|
1267
|
|
|
$rowdata = bigbluebuttonbn_get_recording_data_row($bbbsession, $recording, $tools); |
1268
|
|
|
if ($rowdata != null) { |
1269
|
|
|
$rowdata->date_formatted = str_replace(' ', ' ', $rowdata->date_formatted); |
1270
|
|
|
$row->cells = array($rowdata->recording, $rowdata->activity, $rowdata->description, |
1271
|
|
|
$rowdata->preview, $rowdata->date_formatted, $rowdata->duration_formatted); |
1272
|
|
|
if ($bbbsession['managerecordings']) { |
1273
|
|
|
$row->cells[] = $rowdata->actionbar; |
1274
|
|
|
} |
1275
|
|
|
array_push($table->data, $row); |
1276
|
|
|
} |
1277
|
|
|
} |
1278
|
|
|
} |
1279
|
|
|
|
1280
|
|
|
return $table; |
1281
|
|
|
} |
1282
|
|
|
|
1283
|
|
|
function bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn) { |
1284
|
|
|
$sender = get_admin(); |
1285
|
|
|
|
1286
|
|
|
// Prepare message. |
1287
|
|
|
$msg = new stdClass(); |
1288
|
|
|
|
1289
|
|
|
// Build the message_body. |
1290
|
|
|
$msg->activity_type = ''; |
1291
|
|
|
$msg->activity_title = $bigbluebuttonbn->name; |
1292
|
|
|
$messagetext = '<p>'.get_string('email_body_recording_ready_for', 'bigbluebuttonbn').' '. |
1293
|
|
|
$msg->activity_type.' "'.$msg->activity_title.'" '. |
1294
|
|
|
get_string('email_body_recording_ready_is_ready', 'bigbluebuttonbn').'.</p>'; |
1295
|
|
|
|
1296
|
|
|
bigbluebuttonbn_send_notification($sender, $bigbluebuttonbn, $messagetext); |
1297
|
|
|
} |
1298
|
|
|
|
1299
|
|
|
function bigbluebuttonbn_server_offers_bn_capabilities() { |
1300
|
|
|
// Validates if the server may have extended capabilities. |
1301
|
|
|
$parsedurl = parse_url(bigbluebuttonbn_get_cfg_server_url()); |
1302
|
|
|
if (!isset($parsedurl['host'])) { |
1303
|
|
|
return false; |
1304
|
|
|
} |
1305
|
|
|
|
1306
|
|
|
$h = $parsedurl['host']; |
1307
|
|
|
$hends = explode('.', $h); |
1308
|
|
|
$hendslength = count($hends); |
1309
|
|
|
|
1310
|
|
|
return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks'); |
1311
|
|
|
} |
1312
|
|
|
|
1313
|
|
|
function bigbluebuttonbn_get_locales_for_view() { |
1314
|
|
|
$locales = array( |
1315
|
|
|
'not_started' => get_string('view_message_conference_not_started', 'bigbluebuttonbn'), |
1316
|
|
|
'wait_for_moderator' => get_string('view_message_conference_wait_for_moderator', 'bigbluebuttonbn'), |
1317
|
|
|
'in_progress' => get_string('view_message_conference_in_progress', 'bigbluebuttonbn'), |
1318
|
|
|
'started_at' => get_string('view_message_session_started_at', 'bigbluebuttonbn'), |
1319
|
|
|
'session_no_users' => get_string('view_message_session_no_users', 'bigbluebuttonbn'), |
1320
|
|
|
'session_has_user' => get_string('view_message_session_has_user', 'bigbluebuttonbn'), |
1321
|
|
|
'session_has_users' => get_string('view_message_session_has_users', 'bigbluebuttonbn'), |
1322
|
|
|
'has_joined' => get_string('view_message_has_joined', 'bigbluebuttonbn'), |
1323
|
|
|
'have_joined' => get_string('view_message_have_joined', 'bigbluebuttonbn'), |
1324
|
|
|
'user' => get_string('view_message_user', 'bigbluebuttonbn'), |
1325
|
|
|
'users' => get_string('view_message_users', 'bigbluebuttonbn'), |
1326
|
|
|
'viewer' => get_string('view_message_viewer', 'bigbluebuttonbn'), |
1327
|
|
|
'viewers' => get_string('view_message_viewers', 'bigbluebuttonbn'), |
1328
|
|
|
'moderator' => get_string('view_message_moderator', 'bigbluebuttonbn'), |
1329
|
|
|
'moderators' => get_string('view_message_moderators', 'bigbluebuttonbn'), |
1330
|
|
|
'publish' => get_string('view_recording_list_actionbar_publish', 'bigbluebuttonbn'), |
1331
|
|
|
'publishing' => get_string('view_recording_list_actionbar_publishing', 'bigbluebuttonbn'), |
1332
|
|
|
'unpublish' => get_string('view_recording_list_actionbar_unpublish', 'bigbluebuttonbn'), |
1333
|
|
|
'unpublishing' => get_string('view_recording_list_actionbar_unpublishing', 'bigbluebuttonbn'), |
1334
|
|
|
'modal_title' => get_string('view_recording_modal_title', 'bigbluebuttonbn'), |
1335
|
|
|
'modal_button' => get_string('view_recording_modal_button', 'bigbluebuttonbn'), |
1336
|
|
|
'userlimit_reached' => get_string('view_error_userlimit_reached', 'bigbluebuttonbn'), |
1337
|
|
|
'recording' => get_string('view_recording', 'bigbluebuttonbn'), |
1338
|
|
|
'recording_link' => get_string('view_recording_link', 'bigbluebuttonbn'), |
1339
|
|
|
'recording_link_warning' => get_string('view_recording_link_warning', 'bigbluebuttonbn'), |
1340
|
|
|
'unpublish_confirmation' => get_string('view_recording_unpublish_confirmation', 'bigbluebuttonbn'), |
1341
|
|
|
'unpublish_confirmation_warning_s' => get_string('view_recording_unpublish_confirmation_warning_s', |
1342
|
|
|
'bigbluebuttonbn'), |
1343
|
|
|
'unpublish_confirmation_warning_p' => get_string('view_recording_unpublish_confirmation_warning_p', |
1344
|
|
|
'bigbluebuttonbn'), |
1345
|
|
|
'delete_confirmation' => get_string('view_recording_delete_confirmation', 'bigbluebuttonbn'), |
1346
|
|
|
'delete_confirmation_warning_s' => get_string('view_recording_delete_confirmation_warning_s', |
1347
|
|
|
'bigbluebuttonbn'), |
1348
|
|
|
'delete_confirmation_warning_p' => get_string('view_recording_delete_confirmation_warning_p', |
1349
|
|
|
'bigbluebuttonbn'), |
1350
|
|
|
'import_confirmation' => get_string('view_recording_import_confirmation', 'bigbluebuttonbn'), |
1351
|
|
|
'conference_ended' => get_string('view_message_conference_has_ended', 'bigbluebuttonbn'), |
1352
|
|
|
'conference_not_started' => get_string('view_message_conference_not_started', 'bigbluebuttonbn'), |
1353
|
|
|
); |
1354
|
|
|
|
1355
|
|
|
return $locales; |
1356
|
|
|
} |
1357
|
|
|
|
1358
|
|
|
/** |
1359
|
|
|
* @return string |
1360
|
|
|
*/ |
1361
|
|
|
function bigbluebuttonbn_get_cfg_server_url() { |
1362
|
|
|
global $CFG; |
1363
|
|
|
|
1364
|
|
|
if (isset($CFG->bigbluebuttonbn['server_url'])) { |
1365
|
|
|
return trim(trim($CFG->bigbluebuttonbn['server_url']), '/').'/'; |
1366
|
|
|
} |
1367
|
|
|
|
1368
|
|
|
if (isset($CFG->bigbluebuttonbn_server_url)) { |
1369
|
|
|
return trim(trim($CFG->bigbluebuttonbn_server_url), '/').'/'; |
1370
|
|
|
} |
1371
|
|
|
|
1372
|
|
|
if (isset($CFG->BigBlueButtonBNServerURL)) { |
1373
|
|
|
return trim(trim($CFG->BigBlueButtonBNServerURL), '/').'/'; |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
return BIGBLUEBUTTONBN_DEFAULT_SERVER_URL; |
1377
|
|
|
} |
1378
|
|
|
|
1379
|
|
|
/** |
1380
|
|
|
* @return string |
1381
|
|
|
*/ |
1382
|
|
|
function bigbluebuttonbn_get_cfg_shared_secret() { |
1383
|
|
|
global $CFG; |
1384
|
|
|
|
1385
|
|
|
if (isset($CFG->bigbluebuttonbn['shared_secret'])) { |
1386
|
|
|
return trim($CFG->bigbluebuttonbn['shared_secret']); |
1387
|
|
|
} |
1388
|
|
|
|
1389
|
|
|
if (isset($CFG->bigbluebuttonbn_shared_secret)) { |
1390
|
|
|
return trim($CFG->bigbluebuttonbn_shared_secret); |
1391
|
|
|
} |
1392
|
|
|
|
1393
|
|
|
if (isset($CFG->BigBlueButtonBNSecuritySalt)) { |
1394
|
|
|
return trim($CFG->BigBlueButtonBNSecuritySalt); |
1395
|
|
|
} |
1396
|
|
|
|
1397
|
|
|
return BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET; |
1398
|
|
|
} |
1399
|
|
|
|
1400
|
|
|
/** |
1401
|
|
|
* @return boolean |
1402
|
|
|
*/ |
1403
|
|
|
function bigbluebuttonbn_get_cfg_voicebridge_editable() { |
1404
|
|
|
global $CFG; |
1405
|
|
|
|
1406
|
|
|
if (isset($CFG->bigbluebuttonbn['voicebridge_editable'])) { |
1407
|
|
|
return $CFG->bigbluebuttonbn['voicebridge_editable']; |
1408
|
|
|
} |
1409
|
|
|
|
1410
|
|
|
if (isset($CFG->bigbluebuttonbn_voicebridge_editable)) { |
1411
|
|
|
return $CFG->bigbluebuttonbn_voicebridge_editable; |
1412
|
|
|
} |
1413
|
|
|
|
1414
|
|
|
return false; |
1415
|
|
|
} |
1416
|
|
|
|
1417
|
|
|
/** |
1418
|
|
|
* @return boolean |
1419
|
|
|
*/ |
1420
|
|
|
function bigbluebuttonbn_get_cfg_recording_default() { |
1421
|
|
|
global $CFG; |
1422
|
|
|
|
1423
|
|
|
if (isset($CFG->bigbluebuttonbn['recording_default'])) { |
1424
|
|
|
return $CFG->bigbluebuttonbn['recording_default']; |
1425
|
|
|
} |
1426
|
|
|
|
1427
|
|
|
if (isset($CFG->bigbluebuttonbn_recording_default)) { |
1428
|
|
|
return $CFG->bigbluebuttonbn_recording_default; |
1429
|
|
|
} |
1430
|
|
|
|
1431
|
|
|
return true; |
1432
|
|
|
} |
1433
|
|
|
|
1434
|
|
|
/** |
1435
|
|
|
* @return string |
1436
|
|
|
*/ |
1437
|
|
|
function bigbluebuttonbn_get_cfg_recording_editable() { |
1438
|
|
|
global $CFG; |
1439
|
|
|
|
1440
|
|
|
if (isset($CFG->bigbluebuttonbn['recording_editable'])) { |
1441
|
|
|
return $CFG->bigbluebuttonbn['recording_editable']; |
1442
|
|
|
} |
1443
|
|
|
|
1444
|
|
|
if (isset($CFG->bigbluebuttonbn_recording_editable)) { |
1445
|
|
|
return $CFG->bigbluebuttonbn_recording_editable; |
1446
|
|
|
} |
1447
|
|
|
|
1448
|
|
|
return true; |
1449
|
|
|
} |
1450
|
|
|
|
1451
|
|
|
/** |
1452
|
|
|
* @return boolean |
1453
|
|
|
*/ |
1454
|
|
|
function bigbluebuttonbn_get_cfg_recording_tagging_default() { |
1455
|
|
|
global $CFG; |
1456
|
|
|
|
1457
|
|
|
if (isset($CFG->bigbluebuttonbn['recordingtagging_default'])) { |
1458
|
|
|
return $CFG->bigbluebuttonbn['recordingtagging_default']; |
1459
|
|
|
} |
1460
|
|
|
|
1461
|
|
|
if (isset($CFG->bigbluebuttonbn_recordingtagging_default)) { |
1462
|
|
|
return $CFG->bigbluebuttonbn_recordingtagging_default; |
1463
|
|
|
} |
1464
|
|
|
|
1465
|
|
|
return false; |
1466
|
|
|
} |
1467
|
|
|
|
1468
|
|
|
/** |
1469
|
|
|
* @return boolean |
1470
|
|
|
*/ |
1471
|
|
|
function bigbluebuttonbn_get_cfg_recording_tagging_editable() { |
1472
|
|
|
global $CFG; |
1473
|
|
|
|
1474
|
|
|
if (isset($CFG->bigbluebuttonbn['recordingtagging_editable'])) { |
1475
|
|
|
return $CFG->bigbluebuttonbn['recordingtagging_editable']; |
1476
|
|
|
} |
1477
|
|
|
|
1478
|
|
|
if (isset($CFG->bigbluebuttonbn_recordingtagging_editable)) { |
1479
|
|
|
return $CFG->bigbluebuttonbn_recordingtagging_editable; |
1480
|
|
|
} |
1481
|
|
|
|
1482
|
|
|
return false; |
1483
|
|
|
} |
1484
|
|
|
|
1485
|
|
|
/** |
1486
|
|
|
* @return boolean |
1487
|
|
|
*/ |
1488
|
|
|
function bigbluebuttonbn_get_cfg_recording_icons_enabled() { |
1489
|
|
|
global $CFG; |
1490
|
|
|
|
1491
|
|
|
if (isset($CFG->bigbluebuttonbn['recording_icons_enabled'])) { |
1492
|
|
|
return $CFG->bigbluebuttonbn['recording_icons_enabled']; |
1493
|
|
|
} |
1494
|
|
|
|
1495
|
|
|
if (isset($CFG->bigbluebuttonbn_recording_icons_enabled)) { |
1496
|
|
|
return $CFG->bigbluebuttonbn_recording_icons_enabled; |
1497
|
|
|
} |
1498
|
|
|
|
1499
|
|
|
return true; |
1500
|
|
|
} |
1501
|
|
|
|
1502
|
|
|
/** |
1503
|
|
|
* @return boolean |
1504
|
|
|
*/ |
1505
|
|
|
function bigbluebuttonbn_get_cfg_importrecordings_enabled() { |
1506
|
|
|
global $CFG; |
1507
|
|
|
|
1508
|
|
|
if (isset($CFG->bigbluebuttonbn['importrecordings_enabled'])) { |
1509
|
|
|
return $CFG->bigbluebuttonbn['importrecordings_enabled']; |
1510
|
|
|
} |
1511
|
|
|
|
1512
|
|
|
if (isset($CFG->bigbluebuttonbn_importrecordings_enabled)) { |
1513
|
|
|
return $CFG->bigbluebuttonbn_importrecordings_enabled; |
1514
|
|
|
} |
1515
|
|
|
|
1516
|
|
|
return false; |
1517
|
|
|
} |
1518
|
|
|
|
1519
|
|
|
/** |
1520
|
|
|
* @return boolean |
1521
|
|
|
*/ |
1522
|
|
|
function bigbluebuttonbn_get_cfg_importrecordings_from_deleted_activities_enabled() { |
1523
|
|
|
global $CFG; |
1524
|
|
|
|
1525
|
|
|
if (isset($CFG->bigbluebuttonbn['importrecordings_from_deleted_activities_enabled'])) { |
1526
|
|
|
return $CFG->bigbluebuttonbn['importrecordings_from_deleted_activities_enabled']; |
1527
|
|
|
} |
1528
|
|
|
|
1529
|
|
|
if (isset($CFG->bigbluebuttonbn_importrecordings_from_deleted_activities_enabled)) { |
1530
|
|
|
return $CFG->bigbluebuttonbn_importrecordings_from_deleted_activities_enabled; |
1531
|
|
|
} |
1532
|
|
|
|
1533
|
|
|
return false; |
1534
|
|
|
} |
1535
|
|
|
|
1536
|
|
|
/** |
1537
|
|
|
* @return boolean |
1538
|
|
|
*/ |
1539
|
|
|
function bigbluebuttonbn_get_cfg_waitformoderator_default() { |
1540
|
|
|
global $CFG; |
1541
|
|
|
|
1542
|
|
|
if (isset($CFG->bigbluebuttonbn['waitformoderator_default'])) { |
1543
|
|
|
return $CFG->bigbluebuttonbn['waitformoderator_default']; |
1544
|
|
|
} |
1545
|
|
|
|
1546
|
|
|
if (isset($CFG->bigbluebuttonbn_waitformoderator_default)) { |
1547
|
|
|
return $CFG->bigbluebuttonbn_waitformoderator_default; |
1548
|
|
|
} |
1549
|
|
|
|
1550
|
|
|
return false; |
1551
|
|
|
} |
1552
|
|
|
|
1553
|
|
|
/** |
1554
|
|
|
* @return boolean |
1555
|
|
|
*/ |
1556
|
|
|
function bigbluebuttonbn_get_cfg_waitformoderator_editable() { |
1557
|
|
|
global $CFG; |
1558
|
|
|
|
1559
|
|
|
if (isset($CFG->bigbluebuttonbn['waitformoderator_editable'])) { |
1560
|
|
|
return $CFG->bigbluebuttonbn['waitformoderator_editable']; |
1561
|
|
|
} |
1562
|
|
|
|
1563
|
|
|
if (isset($CFG->bigbluebuttonbn_waitformoderator_editable)) { |
1564
|
|
|
return $CFG->bigbluebuttonbn_waitformoderator_editable; |
1565
|
|
|
} |
1566
|
|
|
|
1567
|
|
|
return true; |
1568
|
|
|
} |
1569
|
|
|
|
1570
|
|
|
/** |
1571
|
|
|
* @return number |
1572
|
|
|
*/ |
1573
|
|
|
function bigbluebuttonbn_get_cfg_waitformoderator_ping_interval() { |
1574
|
|
|
global $CFG; |
1575
|
|
|
|
1576
|
|
|
if (isset($CFG->bigbluebuttonbn['waitformoderator_ping_interval'])) { |
1577
|
|
|
return $CFG->bigbluebuttonbn['waitformoderator_ping_interval']; |
1578
|
|
|
} |
1579
|
|
|
|
1580
|
|
|
if (isset($CFG->bigbluebuttonbn_waitformoderator_ping_interval)) { |
1581
|
|
|
return $CFG->bigbluebuttonbn_waitformoderator_ping_interval; |
1582
|
|
|
} |
1583
|
|
|
|
1584
|
|
|
return 15; |
1585
|
|
|
} |
1586
|
|
|
|
1587
|
|
|
/** |
1588
|
|
|
* @return number |
1589
|
|
|
*/ |
1590
|
|
|
function bigbluebuttonbn_get_cfg_waitformoderator_cache_ttl() { |
1591
|
|
|
global $CFG; |
1592
|
|
|
|
1593
|
|
|
if (isset($CFG->bigbluebuttonbn['waitformoderator_cache_ttl'])) { |
1594
|
|
|
return $CFG->bigbluebuttonbn['waitformoderator_cache_ttl']; |
1595
|
|
|
} |
1596
|
|
|
|
1597
|
|
|
if (isset($CFG->bigbluebuttonbn_waitformoderator_cache_ttl)) { |
1598
|
|
|
return $CFG->bigbluebuttonbn_waitformoderator_cache_ttl; |
1599
|
|
|
} |
1600
|
|
|
|
1601
|
|
|
return 60; |
1602
|
|
|
} |
1603
|
|
|
|
1604
|
|
|
/** |
1605
|
|
|
* @return number |
1606
|
|
|
*/ |
1607
|
|
|
function bigbluebuttonbn_get_cfg_userlimit_default() { |
1608
|
|
|
global $CFG; |
1609
|
|
|
|
1610
|
|
|
if (isset($CFG->bigbluebuttonbn['userlimit_default'])) { |
1611
|
|
|
return $CFG->bigbluebuttonbn['userlimit_default']; |
1612
|
|
|
} |
1613
|
|
|
|
1614
|
|
|
if (isset($CFG->bigbluebuttonbn_userlimit_default)) { |
1615
|
|
|
return $CFG->bigbluebuttonbn_userlimit_default; |
1616
|
|
|
} |
1617
|
|
|
|
1618
|
|
|
return 0; |
1619
|
|
|
} |
1620
|
|
|
|
1621
|
|
|
/** |
1622
|
|
|
* @return boolean |
1623
|
|
|
*/ |
1624
|
|
|
function bigbluebuttonbn_get_cfg_userlimit_editable() { |
1625
|
|
|
global $CFG; |
1626
|
|
|
|
1627
|
|
|
if (isset($CFG->bigbluebuttonbn['userlimit_editable'])) { |
1628
|
|
|
return $CFG->bigbluebuttonbn['userlimit_editable']; |
1629
|
|
|
} |
1630
|
|
|
|
1631
|
|
|
if (isset($CFG->bigbluebuttonbn_userlimit_editable)) { |
1632
|
|
|
return $CFG->bigbluebuttonbn_userlimit_editable; |
1633
|
|
|
} |
1634
|
|
|
|
1635
|
|
|
return false; |
1636
|
|
|
} |
1637
|
|
|
|
1638
|
|
|
/** |
1639
|
|
|
* @return boolean |
1640
|
|
|
*/ |
1641
|
|
|
function bigbluebuttonbn_get_cfg_preuploadpresentation_enabled() { |
1642
|
|
|
global $CFG; |
1643
|
|
|
|
1644
|
|
|
if (!extension_loaded('curl')) { |
1645
|
|
|
return false; |
1646
|
|
|
} |
1647
|
|
|
|
1648
|
|
|
if (isset($CFG->bigbluebuttonbn['preuploadpresentation_enabled'])) { |
1649
|
|
|
return $CFG->bigbluebuttonbn['preuploadpresentation_enabled']; |
1650
|
|
|
} |
1651
|
|
|
|
1652
|
|
|
if (isset($CFG->bigbluebuttonbn_preuploadpresentation_enabled)) { |
1653
|
|
|
return $CFG->bigbluebuttonbn_preuploadpresentation_enabled; |
1654
|
|
|
} |
1655
|
|
|
|
1656
|
|
|
return false; |
1657
|
|
|
} |
1658
|
|
|
|
1659
|
|
|
/** |
1660
|
|
|
* @return boolean |
1661
|
|
|
*/ |
1662
|
|
|
function bigbluebuttonbn_get_cfg_sendnotifications_enabled() { |
1663
|
|
|
global $CFG; |
1664
|
|
|
|
1665
|
|
|
if (isset($CFG->bigbluebuttonbn['sendnotifications_enabled'])) { |
1666
|
|
|
return $CFG->bigbluebuttonbn['sendnotifications_enabled']; |
1667
|
|
|
} |
1668
|
|
|
|
1669
|
|
|
if (isset($CFG->bigbluebuttonbn_sendnotifications_enabled)) { |
1670
|
|
|
return $CFG->bigbluebuttonbn_sendnotifications_enabled; |
1671
|
|
|
} |
1672
|
|
|
|
1673
|
|
|
return false; |
1674
|
|
|
} |
1675
|
|
|
|
1676
|
|
|
/** |
1677
|
|
|
* @return boolean |
1678
|
|
|
*/ |
1679
|
|
|
function bigbluebuttonbn_get_cfg_recordingready_enabled() { |
1680
|
|
|
global $CFG; |
1681
|
|
|
|
1682
|
|
|
if (isset($CFG->bigbluebuttonbn['recordingready_enabled'])) { |
1683
|
|
|
return $CFG->bigbluebuttonbn['recordingready_enabled']; |
1684
|
|
|
} |
1685
|
|
|
|
1686
|
|
|
if (isset($CFG->bigbluebuttonbn_recordingready_enabled)) { |
1687
|
|
|
return $CFG->bigbluebuttonbn_recordingready_enabled; |
1688
|
|
|
} |
1689
|
|
|
|
1690
|
|
|
return false; |
1691
|
|
|
} |
1692
|
|
|
|
1693
|
|
|
/** |
1694
|
|
|
* @return boolean |
1695
|
|
|
*/ |
1696
|
|
|
function bigbluebuttonbn_get_cfg_meetingevents_enabled() { |
1697
|
|
|
global $CFG; |
1698
|
|
|
|
1699
|
|
|
if (isset($CFG->bigbluebuttonbn['meetingevents_enabled'])) { |
1700
|
|
|
return $CFG->bigbluebuttonbn['meetingevents_enabled']; |
1701
|
|
|
} |
1702
|
|
|
|
1703
|
|
|
if (isset($CFG->bigbluebuttonbn_meetingevents_enabled)) { |
1704
|
|
|
return $CFG->bigbluebuttonbn_meetingevents_enabled; |
1705
|
|
|
} |
1706
|
|
|
|
1707
|
|
|
return false; |
1708
|
|
|
} |
1709
|
|
|
|
1710
|
|
|
/** |
1711
|
|
|
* @return string |
1712
|
|
|
*/ |
1713
|
|
|
function bigbluebuttonbn_get_cfg_moderator_default() { |
1714
|
|
|
global $CFG; |
1715
|
|
|
|
1716
|
|
|
if (isset($CFG->bigbluebuttonbn['moderator_default'])) { |
1717
|
|
|
return $CFG->bigbluebuttonbn['moderator_default']; |
1718
|
|
|
} |
1719
|
|
|
|
1720
|
|
|
if (isset($CFG->bigbluebuttonbn_moderator_default)) { |
1721
|
|
|
return $CFG->bigbluebuttonbn_moderator_default; |
1722
|
|
|
} |
1723
|
|
|
|
1724
|
|
|
return 'owner'; |
1725
|
|
|
} |
1726
|
|
|
|
1727
|
|
|
/** |
1728
|
|
|
* @return boolean |
1729
|
|
|
*/ |
1730
|
|
|
function bigbluebuttonbn_get_cfg_scheduled_duration_enabled() { |
1731
|
|
|
global $CFG; |
1732
|
|
|
|
1733
|
|
|
if (isset($CFG->bigbluebuttonbn['scheduled_duration_enabled'])) { |
1734
|
|
|
return $CFG->bigbluebuttonbn['scheduled_duration_enabled']; |
1735
|
|
|
} |
1736
|
|
|
|
1737
|
|
|
if (isset($CFG->bigbluebuttonbn_scheduled_duration_enabled)) { |
1738
|
|
|
return $CFG->bigbluebuttonbn_scheduled_duration_enabled; |
1739
|
|
|
} |
1740
|
|
|
|
1741
|
|
|
return false; |
1742
|
|
|
} |
1743
|
|
|
|
1744
|
|
|
/** |
1745
|
|
|
* @return number |
1746
|
|
|
*/ |
1747
|
|
|
function bigbluebuttonbn_get_cfg_scheduled_duration_compensation() { |
1748
|
|
|
global $CFG; |
1749
|
|
|
|
1750
|
|
|
if (isset($CFG->bigbluebuttonbn['scheduled_duration_compensation'])) { |
1751
|
|
|
return $CFG->bigbluebuttonbn['scheduled_duration_compensation']; |
1752
|
|
|
} |
1753
|
|
|
|
1754
|
|
|
if (isset($CFG->bigbluebuttonbn_scheduled_duration_compensation)) { |
1755
|
|
|
return $CFG->bigbluebuttonbn_scheduled_duration_compensation; |
1756
|
|
|
} |
1757
|
|
|
|
1758
|
|
|
return 10; |
1759
|
|
|
} |
1760
|
|
|
|
1761
|
|
|
/** |
1762
|
|
|
* @return number |
1763
|
|
|
*/ |
1764
|
|
|
function bigbluebuttonbn_get_cfg_scheduled_pre_opening() { |
1765
|
|
|
global $CFG; |
1766
|
|
|
|
1767
|
|
|
if (isset($CFG->bigbluebuttonbn['scheduled_pre_opening'])) { |
1768
|
|
|
return $CFG->bigbluebuttonbn['scheduled_pre_opening']; |
1769
|
|
|
} |
1770
|
|
|
|
1771
|
|
|
if (isset($CFG->bigbluebuttonbn_scheduled_pre_opening)) { |
1772
|
|
|
return $CFG->bigbluebuttonbn_scheduled_pre_opening; |
1773
|
|
|
} |
1774
|
|
|
|
1775
|
|
|
return 10; |
1776
|
|
|
} |
1777
|
|
|
|
1778
|
|
|
/** |
1779
|
|
|
* @return boolean |
1780
|
|
|
*/ |
1781
|
|
|
function bigbluebuttonbn_get_cfg_recordings_html_default() { |
1782
|
|
|
global $CFG; |
1783
|
|
|
|
1784
|
|
|
if (isset($CFG->bigbluebuttonbn['recordings_html_default'])) { |
1785
|
|
|
return $CFG->bigbluebuttonbn['recordings_html_default']; |
1786
|
|
|
} |
1787
|
|
|
|
1788
|
|
|
if (isset($CFG->bigbluebuttonbn_recordings_html_default)) { |
1789
|
|
|
return $CFG->bigbluebuttonbn_recordings_html_default; |
1790
|
|
|
} |
1791
|
|
|
|
1792
|
|
|
return false; |
1793
|
|
|
} |
1794
|
|
|
|
1795
|
|
|
/** |
1796
|
|
|
* @return boolean |
1797
|
|
|
*/ |
1798
|
|
|
function bigbluebuttonbn_get_cfg_recordings_html_editable() { |
1799
|
|
|
global $CFG; |
1800
|
|
|
|
1801
|
|
|
if (isset($CFG->bigbluebuttonbn['recordings_html_editable'])) { |
1802
|
|
|
return $CFG->bigbluebuttonbn['recordings_html_editable']; |
1803
|
|
|
} |
1804
|
|
|
|
1805
|
|
|
if (isset($CFG->bigbluebuttonbn_recordings_html_editable)) { |
1806
|
|
|
return $CFG->bigbluebuttonbn_recordings_html_editable; |
1807
|
|
|
} |
1808
|
|
|
|
1809
|
|
|
return false; |
1810
|
|
|
} |
1811
|
|
|
|
1812
|
|
|
/** |
1813
|
|
|
* @return boolean |
1814
|
|
|
*/ |
1815
|
|
|
function bigbluebuttonbn_get_cfg_recordings_deleted_activities_default() { |
1816
|
|
|
global $CFG; |
1817
|
|
|
|
1818
|
|
|
if (isset($CFG->bigbluebuttonbn['recordings_deleted_activities_default'])) { |
1819
|
|
|
return $CFG->bigbluebuttonbn['recordings_deleted_activities_default']; |
1820
|
|
|
} |
1821
|
|
|
|
1822
|
|
|
if (isset($CFG->bigbluebuttonbn_recordings_deleted_activities_default)) { |
1823
|
|
|
return $CFG->bigbluebuttonbn_recordings_deleted_activities_default; |
1824
|
|
|
} |
1825
|
|
|
|
1826
|
|
|
return false; |
1827
|
|
|
} |
1828
|
|
|
|
1829
|
|
|
/** |
1830
|
|
|
* @return boolean |
1831
|
|
|
*/ |
1832
|
|
|
function bigbluebuttonbn_get_cfg_recordings_deleted_activities_editable() { |
1833
|
|
|
global $CFG; |
1834
|
|
|
|
1835
|
|
|
if (isset($CFG->bigbluebuttonbn['recordings_deleted_activities_editable'])) { |
1836
|
|
|
return $CFG->bigbluebuttonbn['recordings_deleted_activities_editable']; |
1837
|
|
|
} |
1838
|
|
|
|
1839
|
|
|
if (isset($CFG->bigbluebuttonbn_recordings_deleted_activities_editable)) { |
1840
|
|
|
return $CFG->bigbluebuttonbn_recordings_deleted_activities_editable; |
1841
|
|
|
} |
1842
|
|
|
|
1843
|
|
|
return false; |
1844
|
|
|
} |
1845
|
|
|
|
1846
|
|
|
/** |
1847
|
|
|
* @return array |
1848
|
|
|
*/ |
1849
|
|
|
function bigbluebuttonbn_get_cfg_options() { |
1850
|
|
|
return [ |
1851
|
|
|
'voicebridge_editable' => bigbluebuttonbn_get_cfg_voicebridge_editable(), |
1852
|
|
|
'recording_default' => bigbluebuttonbn_get_cfg_recording_default(), |
1853
|
|
|
'recording_editable' => bigbluebuttonbn_get_cfg_recording_editable(), |
1854
|
|
|
'recording_tagging_default' => bigbluebuttonbn_get_cfg_recording_tagging_default(), |
1855
|
|
|
'recording_tagging_editable' => bigbluebuttonbn_get_cfg_recording_tagging_editable(), |
1856
|
|
|
'waitformoderator_default' => bigbluebuttonbn_get_cfg_waitformoderator_default(), |
1857
|
|
|
'waitformoderator_editable' => bigbluebuttonbn_get_cfg_waitformoderator_editable(), |
1858
|
|
|
'userlimit_default' => bigbluebuttonbn_get_cfg_userlimit_default(), |
1859
|
|
|
'userlimit_editable' => bigbluebuttonbn_get_cfg_userlimit_editable(), |
1860
|
|
|
'preuploadpresentation_enabled' => bigbluebuttonbn_get_cfg_preuploadpresentation_enabled(), |
1861
|
|
|
'sendnotifications_enabled' => bigbluebuttonbn_get_cfg_sendnotifications_enabled(), |
1862
|
|
|
'recordings_html_default' => bigbluebuttonbn_get_cfg_recordings_html_default(), |
1863
|
|
|
'recordings_html_editable' => bigbluebuttonbn_get_cfg_recordings_html_editable(), |
1864
|
|
|
'recordings_deleted_activities_default' => bigbluebuttonbn_get_cfg_recordings_deleted_activities_default(), |
1865
|
|
|
'recordings_deleted_activities_editable' => bigbluebuttonbn_get_cfg_recordings_deleted_activities_editable(), |
1866
|
|
|
'recording_icons_enabled' => bigbluebuttonbn_get_cfg_recording_icons_enabled(), |
1867
|
|
|
'instance_type_enabled' => bigbluebuttonbn_recordings_enabled(), |
1868
|
|
|
'instance_type_default' => BIGBLUEBUTTONBN_TYPE_ALL, |
1869
|
|
|
]; |
1870
|
|
|
} |
1871
|
|
|
|
1872
|
|
|
function bigbluebuttonbn_import_get_courses_for_select(array $bbbsession) { |
1873
|
|
|
if ($bbbsession['administrator']) { |
1874
|
|
|
$courses = get_courses('all', 'c.id ASC', 'c.id,c.shortname,c.fullname'); |
1875
|
|
|
// It includes the name of the site as a course (category 0), so remove the first one. |
1876
|
|
|
unset($courses['1']); |
1877
|
|
|
} else { |
1878
|
|
|
$courses = enrol_get_users_courses($bbbsession['userID'], false, 'id,shortname,fullname'); |
1879
|
|
|
} |
1880
|
|
|
|
1881
|
|
|
$coursesforselect = []; |
1882
|
|
|
foreach ($courses as $course) { |
1883
|
|
|
$coursesforselect[$course->id] = $course->fullname; |
1884
|
|
|
} |
1885
|
|
|
|
1886
|
|
|
return $coursesforselect; |
1887
|
|
|
} |
1888
|
|
|
|
1889
|
|
|
function bigbluebutton_output_recording_table($bbbsession, $recordings, $tools = ['publishing', 'deleting']) { |
1890
|
|
|
if (isset($recordings) && !empty($recordings)) { |
1891
|
|
|
// There are recordings for this meeting. |
1892
|
|
|
$table = bigbluebuttonbn_get_recording_table($bbbsession, $recordings, $tools); |
1893
|
|
|
} |
1894
|
|
|
|
1895
|
|
|
if (!isset($table) || !isset($table->data)) { |
1896
|
|
|
// Render a table qith "No recordings". |
1897
|
|
|
return html_writer::div(get_string('view_message_norecordings', 'bigbluebuttonbn'), '', |
1898
|
|
|
array('id' => 'bigbluebuttonbn_html_table')); |
1899
|
|
|
} |
1900
|
|
|
|
1901
|
|
|
// Render the table. |
1902
|
|
|
return html_writer::div(html_writer::table($table), '', array('id' => 'bigbluebuttonbn_html_table')); |
1903
|
|
|
} |
1904
|
|
|
|
1905
|
|
|
function bigbluebuttonbn_html2text($html, $len) { |
1906
|
|
|
$text = strip_tags($html); |
1907
|
|
|
$text = str_replace(' ', ' ', $text); |
1908
|
|
|
$text = substr($text, 0, $len); |
1909
|
|
|
if (strlen($text) > $len) { |
1910
|
|
|
$text .= '...'; |
1911
|
|
|
} |
1912
|
|
|
|
1913
|
|
|
return $text; |
1914
|
|
|
} |
1915
|
|
|
|
1916
|
|
|
function bigbluebuttonbn_get_tags($id) { |
1917
|
|
|
$tags = ''; |
1918
|
|
|
$tagsarray = core_tag_tag::get_item_tags_array('core', 'course_modules', $id); |
1919
|
|
|
foreach ($tagsarray as $tag) { |
1920
|
|
|
$tags .= ($tags == '') ? $tag : ','.$tag; |
1921
|
|
|
} |
1922
|
|
|
|
1923
|
|
|
return $tags; |
1924
|
|
|
} |
1925
|
|
|
|
1926
|
|
|
/** |
1927
|
|
|
* helper function to retrieve recordings from the BigBlueButton. The references are stored as events |
1928
|
|
|
* in bigbluebuttonbn_logs. |
1929
|
|
|
* |
1930
|
|
|
* @param string $courseid |
1931
|
|
|
* @param string $bigbluebuttonbnid |
1932
|
|
|
* @param bool $subset |
1933
|
|
|
* @param bool $includedeleted |
1934
|
|
|
* |
1935
|
|
|
* @return associative array containing the recordings indexed by recordID, each recording is also a |
1936
|
|
|
* non sequential associative array itself that corresponds to the actual recording in BBB |
1937
|
|
|
*/ |
1938
|
|
|
function bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid = null, |
1939
|
|
|
$subset = true, $includedeleted = false) { |
1940
|
|
|
global $DB; |
1941
|
|
|
|
1942
|
|
|
// Gather the bigbluebuttonbnids whose meetingids should be included in the getRecordings request'. |
1943
|
|
|
$select = "id <> '{$bigbluebuttonbnid}' AND course = '{$courseid}'"; |
1944
|
|
|
$selectdeleted = "courseid = '{$courseid}' AND bigbluebuttonbnid <> '{$bigbluebuttonbnid}' AND log = '". |
1945
|
|
|
BIGBLUEBUTTONBN_LOG_EVENT_DELETE."' AND meta like '%has_recordings%' AND meta like '%true%'"; |
1946
|
|
|
if ($bigbluebuttonbnid === null) { |
1947
|
|
|
$select = "course = '{$courseid}'"; |
1948
|
|
|
$selectdeleted = "courseid = '{$courseid}' AND log = '".BIGBLUEBUTTONBN_LOG_EVENT_DELETE. |
1949
|
|
|
"' AND meta like '%has_recordings%' AND meta like '%true%'"; |
1950
|
|
|
} else if ($subset) { |
1951
|
|
|
$select = "id = '{$bigbluebuttonbnid}'"; |
1952
|
|
|
$selectdeleted = "bigbluebuttonbnid = '{$bigbluebuttonbnid}' AND log = '".BIGBLUEBUTTONBN_LOG_EVENT_DELETE. |
1953
|
|
|
"' AND meta like '%has_recordings%' AND meta like '%true%'"; |
1954
|
|
|
} |
1955
|
|
|
$bigbluebuttonbns = $DB->get_records_select_menu('bigbluebuttonbn', $select, null, 'id', 'id, meetingid'); |
1956
|
|
|
|
1957
|
|
|
/* Consider logs from deleted bigbluebuttonbn instances whose meetingids should be included in |
1958
|
|
|
* the getRecordings request. */ |
1959
|
|
|
if ($includedeleted) { |
1960
|
|
|
$bigbluebuttonbnsdel = $DB->get_records_select_menu('bigbluebuttonbn_logs', $selectdeleted, null, |
1961
|
|
|
'bigbluebuttonbnid', 'bigbluebuttonbnid, meetingid'); |
1962
|
|
|
if (!empty($bigbluebuttonbnsdel)) { |
1963
|
|
|
// Merge bigbluebuttonbnis from deleted instances, only keys are relevant. |
1964
|
|
|
// Artimetic merge is used in order to keep the keys. |
1965
|
|
|
$bigbluebuttonbns += $bigbluebuttonbnsdel; |
1966
|
|
|
} |
1967
|
|
|
} |
1968
|
|
|
|
1969
|
|
|
// Gather the meetingids from bigbluebuttonbn logs that include a create with record=true. |
1970
|
|
|
$recordings = array(); |
1971
|
|
|
if (!empty($bigbluebuttonbns)) { |
1972
|
|
|
// Prepare select for loading records based on existent bigbluebuttonbns. |
1973
|
|
|
$sql = 'SELECT DISTINCT meetingid, bigbluebuttonbnid FROM {bigbluebuttonbn_logs} WHERE '; |
1974
|
|
|
$sql .= '(bigbluebuttonbnid='.implode(' OR bigbluebuttonbnid=', array_keys($bigbluebuttonbns)).')'; |
1975
|
|
|
// Include only Create events and exclude those with record not true. |
1976
|
|
|
$sql .= ' AND log = ? AND meta LIKE ? AND meta LIKE ?'; |
1977
|
|
|
// Execute select for loading records based on existent bigbluebuttonbns. |
1978
|
|
|
$records = $DB->get_records_sql_menu($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_CREATE, '%record%', '%true%')); |
1979
|
|
|
// Get actual recordings. |
1980
|
|
|
$recordings = bigbluebuttonbn_get_recordings_array(array_keys($records)); |
1981
|
|
|
} |
1982
|
|
|
|
1983
|
|
|
// Get recording links. |
1984
|
|
|
$recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, $subset); |
1985
|
|
|
|
1986
|
|
|
/* Perform aritmetic add instead of merge so the imported recordings corresponding to existent recordings |
1987
|
|
|
* are not included. */ |
1988
|
|
|
return $recordings + $recordingsimported; |
1989
|
|
|
} |
1990
|
|
|
|
1991
|
|
|
function bigbluebuttonbn_unset_existent_recordings_already_imported($recordings, $courseid, $bigbluebuttonbnid) { |
1992
|
|
|
$recordingsimported = bigbluebuttonbn_get_recordings_imported_array($courseid, $bigbluebuttonbnid, true); |
1993
|
|
|
|
1994
|
|
|
foreach ($recordings as $key => $recording) { |
1995
|
|
|
if (isset($recordingsimported[$recording['recordID']])) { |
1996
|
|
|
unset($recordings[$key]); |
1997
|
|
|
} |
1998
|
|
|
} |
1999
|
|
|
|
2000
|
|
|
return $recordings; |
2001
|
|
|
} |
2002
|
|
|
|
2003
|
|
|
function bigbluebuttonbn_get_count_recording_imported_instances($recordid) { |
2004
|
|
|
global $DB; |
2005
|
|
|
|
2006
|
|
|
$sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?'; |
2007
|
|
|
|
2008
|
|
|
return $DB->count_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', "%{$recordid}%")); |
2009
|
|
|
} |
2010
|
|
|
|
2011
|
|
|
function bigbluebuttonbn_get_recording_imported_instances($recordid) { |
2012
|
|
|
global $DB; |
2013
|
|
|
|
2014
|
|
|
$sql = 'SELECT * FROM {bigbluebuttonbn_logs} WHERE log = ? AND meta LIKE ? AND meta LIKE ?'; |
2015
|
|
|
$recordingsimported = $DB->get_records_sql($sql, array(BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, '%recordID%', |
2016
|
|
|
"%{$recordid}%")); |
2017
|
|
|
|
2018
|
|
|
return $recordingsimported; |
2019
|
|
|
} |
2020
|
|
|
|
2021
|
|
|
function bigbluebuttonbn_get_instance_type_profiles() { |
2022
|
|
|
$instanceprofiles = array( |
2023
|
|
|
array('id' => BIGBLUEBUTTONBN_TYPE_ALL, 'name' => get_string('instance_type_default', 'bigbluebuttonbn'), |
2024
|
|
|
'features' => array('all')), |
2025
|
|
|
array('id' => BIGBLUEBUTTONBN_TYPE_ROOM_ONLY, 'name' => get_string('instance_type_room_only', 'bigbluebuttonbn'), |
2026
|
|
|
'features' => array('showroom', 'welcomemessage', 'voicebridge', 'waitformoderator', 'userlimit', 'recording', |
2027
|
|
|
'recordingtagging', 'sendnotifications', 'preuploadpresentation', 'permissions', 'schedule', 'groups')), |
2028
|
|
|
array('id' => BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY, 'name' => get_string('instance_type_recording_only', |
2029
|
|
|
'bigbluebuttonbn'), 'features' => array('showrecordings', 'importrecordings')), |
2030
|
|
|
); |
2031
|
|
|
|
2032
|
|
|
return $instanceprofiles; |
2033
|
|
|
} |
2034
|
|
|
|
2035
|
|
|
function bigbluebuttonbn_get_instance_profiles_array($profiles = null) { |
2036
|
|
|
if (is_null($profiles) || empty($profiles)) { |
2037
|
|
|
$profiles = bigbluebuttonbn_get_instanceprofiles(); |
2038
|
|
|
} |
2039
|
|
|
|
2040
|
|
|
$profilesarray = array(); |
2041
|
|
|
|
2042
|
|
|
foreach ($profiles as $profile) { |
2043
|
|
|
$profilesarray += array("{$profile['id']}" => $profile['name']); |
2044
|
|
|
} |
2045
|
|
|
|
2046
|
|
|
return $profilesarray; |
2047
|
|
|
} |
2048
|
|
|
|
2049
|
|
|
function bigbluebuttonbn_format_activity_time($time) { |
2050
|
|
|
$activitytime = ''; |
2051
|
|
|
if ($time) { |
2052
|
|
|
$activitytime = calendar_day_representation($time).' '. |
2053
|
|
|
get_string('mod_form_field_notification_msg_at', 'bigbluebuttonbn').' '. |
2054
|
|
|
calendar_time_representation($time); |
2055
|
|
|
} |
2056
|
|
|
|
2057
|
|
|
return $activitytime; |
2058
|
|
|
} |
2059
|
|
|
|
2060
|
|
|
function bigbluebuttonbn_recordings_enabled() { |
2061
|
|
|
global $CFG; |
2062
|
|
|
|
2063
|
|
|
return !(isset($CFG->bigbluebuttonbn['recording_default)']) && |
2064
|
|
|
isset($CFG->bigbluebuttonbn['recording_editable'])); |
2065
|
|
|
} |
2066
|
|
|
|
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.