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