1
|
|
|
<?php |
2
|
|
|
/* For licensing terms, see /license.txt */ |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* Class bbb |
6
|
|
|
* This script initiates a video conference session, calling the BigBlueButton |
7
|
|
|
* API |
8
|
|
|
* @package chamilo.plugin.bigbluebutton |
9
|
|
|
* |
10
|
|
|
* BigBlueButton-Chamilo connector class |
11
|
|
|
*/ |
12
|
|
|
//namespace Chamilo\Plugin\BBB; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Class bbb |
16
|
|
|
* @package Chamilo\Plugin\BBB |
17
|
|
|
*/ |
18
|
|
|
class bbb |
19
|
|
|
{ |
20
|
|
|
public $url; |
21
|
|
|
public $salt; |
22
|
|
|
public $api; |
23
|
|
|
public $userCompleteName = ''; |
24
|
|
|
public $protocol = 'http://'; |
25
|
|
|
public $debug = false; |
26
|
|
|
public $logoutUrl = ''; |
27
|
|
|
public $pluginEnabled = false; |
28
|
|
|
public $enableGlobalConference = false; |
29
|
|
|
public $isGlobalConference = false; |
30
|
|
|
public $groupSupport = false; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Constructor (generates a connection to the API and the Chamilo settings |
34
|
|
|
* required for the connection to the video conference server) |
35
|
|
|
* @param string $host |
36
|
|
|
* @param string $salt |
37
|
|
|
* @param bool $isGlobalConference |
38
|
|
|
*/ |
39
|
|
|
public function __construct($host = '', $salt = '', $isGlobalConference = false) |
40
|
|
|
{ |
41
|
|
|
// Initialize video server settings from global settings |
42
|
|
|
$plugin = BBBPlugin::create(); |
43
|
|
|
|
44
|
|
|
$bbbPlugin = $plugin->get('tool_enable'); |
45
|
|
|
|
46
|
|
|
$bbb_host = !empty($host) ? $host : $plugin->get('host'); |
47
|
|
|
$bbb_salt = !empty($salt) ? $salt : $plugin->get('salt'); |
48
|
|
|
|
49
|
|
|
$this->logoutUrl = $this->getListingUrl(); |
50
|
|
|
$this->table = Database::get_main_table('plugin_bbb_meeting'); |
51
|
|
|
$this->enableGlobalConference = $plugin->get('enable_global_conference'); |
52
|
|
|
$this->isGlobalConference = (bool) $isGlobalConference; |
53
|
|
|
|
54
|
|
|
$columns = Database::listTableColumns($this->table); |
55
|
|
|
$this->groupSupport = isset($columns['group_id']) ? true : false; |
56
|
|
|
|
57
|
|
|
if ($this->groupSupport) { |
58
|
|
|
// Plugin check |
59
|
|
|
$this->groupSupport = (bool) $plugin->get('enable_conference_in_course_groups'); |
60
|
|
|
if ($this->groupSupport) { |
61
|
|
|
|
62
|
|
|
// Platform check |
63
|
|
|
$bbbSetting = api_get_setting('bbb_enable_conference_in_course_groups'); |
64
|
|
|
$bbbSetting = isset($bbbSetting['bbb']) ? $bbbSetting['bbb'] === 'true' : false; |
65
|
|
|
|
66
|
|
|
if ($bbbSetting) { |
67
|
|
|
// Course check |
68
|
|
|
$courseInfo = api_get_course_info(); |
69
|
|
|
|
70
|
|
|
if ($courseInfo) { |
71
|
|
|
$this->groupSupport = api_get_course_setting('bbb_enable_conference_in_groups') === '1'; |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
if ($bbbPlugin == true) { |
78
|
|
|
$userInfo = api_get_user_info(); |
79
|
|
|
$this->userCompleteName = $userInfo['complete_name']; |
80
|
|
|
$this->salt = $bbb_salt; |
81
|
|
|
$info = parse_url($bbb_host); |
82
|
|
|
$this->url = $bbb_host.'/bigbluebutton/'; |
83
|
|
|
if (isset($info['scheme'])) { |
84
|
|
|
$this->protocol = $info['scheme'].'://'; |
85
|
|
|
$this->url = str_replace($this->protocol, '', $this->url); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
// Setting BBB api |
89
|
|
|
define('CONFIG_SECURITY_SALT', $this->salt); |
90
|
|
|
define('CONFIG_SERVER_BASE_URL', $this->url); |
91
|
|
|
|
92
|
|
|
$this->api = new BigBlueButtonBN(); |
93
|
|
|
$this->pluginEnabled = true; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* @return bool |
99
|
|
|
*/ |
100
|
|
|
public function isGlobalConferenceEnabled() |
101
|
|
|
{ |
102
|
|
|
return (bool) $this->enableGlobalConference; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @return bool |
107
|
|
|
*/ |
108
|
|
|
public function isGlobalConference() |
109
|
|
|
{ |
110
|
|
|
if ($this->isGlobalConferenceEnabled() === false) { |
111
|
|
|
|
112
|
|
|
return false; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
return (bool) $this->isGlobalConference; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @return bool |
120
|
|
|
*/ |
121
|
|
|
public function hasGroupSupport() |
122
|
|
|
{ |
123
|
|
|
return $this->groupSupport; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Checks whether a user is teacher in the current course |
128
|
|
|
* @return bool True if the user can be considered a teacher in this course, false otherwise |
129
|
|
|
*/ |
130
|
|
|
public function isConferenceManager() |
131
|
|
|
{ |
132
|
|
|
return api_is_course_admin() || api_is_coach() || api_is_platform_admin(); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* See this file in you BBB to set up default values |
137
|
|
|
* @param array $params Array of parameters that will be completed if not containing all expected variables |
138
|
|
|
|
139
|
|
|
/var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties |
140
|
|
|
* |
141
|
|
|
More record information: |
142
|
|
|
http://code.google.com/p/bigbluebutton/wiki/RecordPlaybackSpecification |
143
|
|
|
|
144
|
|
|
# Default maximum number of users a meeting can have. |
145
|
|
|
# Doesn't get enforced yet but is the default value when the create |
146
|
|
|
# API doesn't pass a value. |
147
|
|
|
defaultMaxUsers=20 |
148
|
|
|
|
149
|
|
|
# Default duration of the meeting in minutes. |
150
|
|
|
# Current default is 0 (meeting doesn't end). |
151
|
|
|
defaultMeetingDuration=0 |
152
|
|
|
|
153
|
|
|
# Remove the meeting from memory when the end API is called. |
154
|
|
|
# This allows 3rd-party apps to recycle the meeting right-away |
155
|
|
|
# instead of waiting for the meeting to expire (see below). |
156
|
|
|
removeMeetingWhenEnded=false |
157
|
|
|
|
158
|
|
|
# The number of minutes before the system removes the meeting from memory. |
159
|
|
|
defaultMeetingExpireDuration=1 |
160
|
|
|
|
161
|
|
|
# The number of minutes the system waits when a meeting is created and when |
162
|
|
|
# a user joins. If after this period, a user hasn't joined, the meeting is |
163
|
|
|
# removed from memory. |
164
|
|
|
defaultMeetingCreateJoinDuration=5 |
165
|
|
|
* |
166
|
|
|
* @return mixed |
167
|
|
|
*/ |
168
|
|
|
public function createMeeting($params) |
169
|
|
|
{ |
170
|
|
|
$courseCode = api_get_course_id(); |
171
|
|
|
$params['c_id'] = api_get_course_int_id(); |
172
|
|
|
$params['session_id'] = api_get_session_id(); |
173
|
|
|
|
174
|
|
|
if ($this->hasGroupSupport()) { |
175
|
|
|
$params['group_id'] = api_get_group_id(); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
$params['attendee_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $courseCode; |
179
|
|
|
$attendeePassword = $params['attendee_pw']; |
180
|
|
|
$params['moderator_pw'] = isset($params['moderator_pw']) ? $params['moderator_pw'] : $this->getModMeetingPassword(); |
181
|
|
|
$moderatorPassword = $params['moderator_pw']; |
182
|
|
|
|
183
|
|
|
$params['record'] = api_get_course_setting('big_blue_button_record_and_store', $courseCode) == 1 ? true : false; |
184
|
|
|
$max = api_get_course_setting('big_blue_button_max_students_allowed', $courseCode); |
185
|
|
|
$max = isset($max) ? $max : -1; |
186
|
|
|
|
187
|
|
|
$params['status'] = 1; |
188
|
|
|
// Generate a pseudo-global-unique-id to avoid clash of conferences on |
189
|
|
|
// the same BBB server with several Chamilo portals |
190
|
|
|
$params['remote_id'] = uniqid(true, true); |
191
|
|
|
// Each simultaneous conference room needs to have a different |
192
|
|
|
// voice_bridge composed of a 5 digits number, so generating a random one |
193
|
|
|
$params['voice_bridge'] = rand(10000, 99999); |
194
|
|
|
|
195
|
|
|
if ($this->debug) { |
196
|
|
|
error_log("enter create_meeting ".print_r($params, 1)); |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
$params['created_at'] = api_get_utc_datetime(); |
200
|
|
|
$id = Database::insert($this->table, $params); |
201
|
|
|
|
202
|
|
|
if ($id) { |
203
|
|
|
if ($this->debug) { |
204
|
|
|
error_log("create_meeting: $id "); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
$meetingName = isset($params['meeting_name']) ? $params['meeting_name'] : $this->getCurrentVideoConferenceName(); |
208
|
|
|
$welcomeMessage = isset($params['welcome_msg']) ? $params['welcome_msg'] : null; |
209
|
|
|
$record = isset($params['record']) && $params['record'] ? 'true' : 'false'; |
210
|
|
|
$duration = isset($params['duration']) ? intval($params['duration']) : 0; |
211
|
|
|
// This setting currently limits the maximum conference duration, |
212
|
|
|
// to avoid lingering sessions on the video-conference server #6261 |
213
|
|
|
$duration = 300; |
214
|
|
|
|
215
|
|
|
$bbbParams = array( |
216
|
|
|
'meetingId' => $params['remote_id'], // REQUIRED |
217
|
|
|
'meetingName' => $meetingName, // REQUIRED |
218
|
|
|
'attendeePw' => $attendeePassword, // Match this value in getJoinMeetingURL() to join as attendee. |
219
|
|
|
'moderatorPw' => $moderatorPassword, // Match this value in getJoinMeetingURL() to join as moderator. |
220
|
|
|
'welcomeMsg' => $welcomeMessage, // ''= use default. Change to customize. |
221
|
|
|
'dialNumber' => '', // The main number to call into. Optional. |
222
|
|
|
'voiceBridge' => $params['voice_bridge'], // PIN to join voice. Required. |
223
|
|
|
'webVoice' => '', // Alphanumeric to join voice. Optional. |
224
|
|
|
'logoutUrl' => $this->logoutUrl, |
225
|
|
|
'maxParticipants' => $max, // Optional. -1 = unlimitted. Not supported in BBB. [number] |
226
|
|
|
'record' => $record, // New. 'true' will tell BBB to record the meeting. |
227
|
|
|
'duration' => $duration, // Default = 0 which means no set duration in minutes. [number] |
228
|
|
|
//'meta_category' => '', // Use to pass additional info to BBB server. See API docs. |
229
|
|
|
); |
230
|
|
|
|
231
|
|
|
if ($this->debug) { |
232
|
|
|
error_log("create_meeting params: ".print_r($bbbParams,1)); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$status = false; |
236
|
|
|
$meeting = null; |
237
|
|
|
|
238
|
|
|
while ($status === false) { |
239
|
|
|
$result = $this->api->createMeetingWithXmlResponseArray( |
240
|
|
|
$bbbParams |
241
|
|
|
); |
242
|
|
|
if (isset($result) && strval($result['returncode']) == 'SUCCESS') { |
243
|
|
|
if ($this->debug) { |
244
|
|
|
error_log( |
245
|
|
|
"create_meeting result: " . print_r($result, 1) |
246
|
|
|
); |
247
|
|
|
} |
248
|
|
|
$meeting = $this->joinMeeting($meetingName, true); |
249
|
|
|
|
250
|
|
|
return $meeting; |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
return $this->logoutUrl; |
255
|
|
|
} |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* Save a participant in a meeting room |
260
|
|
|
* @param int $meetingId |
261
|
|
|
* @param int $participantId |
262
|
|
|
* @return false|int The last inserted ID. Otherwise return false |
263
|
|
|
*/ |
264
|
|
|
public function saveParticipant($meetingId, $participantId) |
265
|
|
|
{ |
266
|
|
|
return Database::insert( |
267
|
|
|
'plugin_bbb_room', |
268
|
|
|
[ |
269
|
|
|
'meeting_id' => $meetingId, |
270
|
|
|
'participant_id' => $participantId, |
271
|
|
|
'in_at' => api_get_utc_datetime(), |
272
|
|
|
'out_at' => api_get_utc_datetime() |
273
|
|
|
] |
274
|
|
|
); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Tells whether the given meeting exists and is running |
279
|
|
|
* (using course code as name) |
280
|
|
|
* @param string $meetingName Meeting name (usually the course code) |
281
|
|
|
* |
282
|
|
|
* @return bool True if meeting exists, false otherwise |
283
|
|
|
* @assert ('') === false |
284
|
|
|
* @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false |
285
|
|
|
*/ |
286
|
|
|
public function meetingExists($meetingName) |
287
|
|
|
{ |
288
|
|
|
if (empty($meetingName)) { |
289
|
|
|
|
290
|
|
|
return false; |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
$courseId = api_get_course_int_id(); |
294
|
|
|
$sessionId = api_get_session_id(); |
295
|
|
|
$conditions = array( |
296
|
|
|
'where' => array( |
297
|
|
|
'c_id = ? AND session_id = ? AND meeting_name = ? AND status = 1 ' => |
298
|
|
|
array($courseId, $sessionId, $meetingName) |
299
|
|
|
) |
300
|
|
|
); |
301
|
|
|
|
302
|
|
View Code Duplication |
if ($this->hasGroupSupport()) { |
303
|
|
|
$groupId = api_get_group_id(); |
304
|
|
|
$conditions = array( |
305
|
|
|
'where' => array( |
306
|
|
|
'c_id = ? AND session_id = ? AND meeting_name = ? AND group_id = ? AND status = 1 ' => |
307
|
|
|
array($courseId, $sessionId, $meetingName, $groupId) |
308
|
|
|
) |
309
|
|
|
); |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
$meetingData = Database::select( |
313
|
|
|
'*', |
314
|
|
|
$this->table, |
315
|
|
|
$conditions, |
316
|
|
|
'first' |
317
|
|
|
); |
318
|
|
|
|
319
|
|
|
|
320
|
|
|
if ($this->debug) { |
321
|
|
|
error_log("meeting_exists ".print_r($meetingData, 1)); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
if (empty($meetingData)) { |
325
|
|
|
|
326
|
|
|
return false; |
327
|
|
|
} else { |
328
|
|
|
return true; |
329
|
|
|
} |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* Returns a meeting "join" URL |
334
|
|
|
* @param string The name of the meeting (usually the course code) |
335
|
|
|
* @return mixed The URL to join the meeting, or false on error |
336
|
|
|
* @todo implement moderator pass |
337
|
|
|
* @assert ('') === false |
338
|
|
|
* @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false |
339
|
|
|
*/ |
340
|
|
|
public function joinMeeting($meetingName, $loop = false) |
341
|
|
|
{ |
342
|
|
|
if (empty($meetingName)) { |
343
|
|
|
return false; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
$pass = $this->getUserMeetingPassword(); |
347
|
|
|
|
348
|
|
|
$meetingData = Database::select( |
349
|
|
|
'*', |
350
|
|
|
$this->table, |
351
|
|
|
array('where' => array('meeting_name = ? AND status = 1 ' => $meetingName)), |
352
|
|
|
'first' |
353
|
|
|
); |
354
|
|
|
|
355
|
|
|
if (empty($meetingData) || !is_array($meetingData)) { |
356
|
|
|
if ($this->debug) { |
357
|
|
|
error_log("meeting does not exist: $meetingName"); |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
return false; |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
$params = array( |
364
|
|
|
'meetingId' => $meetingData['remote_id'], |
365
|
|
|
// -- REQUIRED - The unique id for the meeting |
366
|
|
|
'password' => $this->getModMeetingPassword() |
367
|
|
|
// -- REQUIRED - The moderator password for the meeting |
368
|
|
|
); |
369
|
|
|
|
370
|
|
|
$status = false; |
371
|
|
|
$meetingInfoExists = false; |
372
|
|
|
while ($status === false) { |
373
|
|
|
|
374
|
|
|
$meetingIsRunningInfo = $this->getMeetingInfo($params); |
375
|
|
View Code Duplication |
if ($meetingIsRunningInfo === false) { |
376
|
|
|
//checking with the remote_id didn't work, so just in case and |
377
|
|
|
// to provide backwards support, check with the id |
378
|
|
|
$params = array( |
379
|
|
|
'meetingId' => $meetingData['id'], |
380
|
|
|
// -- REQUIRED - The unique id for the meeting |
381
|
|
|
'password' => $this->getModMeetingPassword() |
382
|
|
|
// -- REQUIRED - The moderator password for the meeting |
383
|
|
|
); |
384
|
|
|
$meetingIsRunningInfo = $this->getMeetingInfo($params); |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
if ($this->debug) { |
388
|
|
|
error_log(print_r($meetingIsRunningInfo, 1)); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
if (strval($meetingIsRunningInfo['returncode']) == 'SUCCESS' && |
392
|
|
|
isset($meetingIsRunningInfo['meetingName']) && |
393
|
|
|
!empty($meetingIsRunningInfo['meetingName']) |
394
|
|
|
//strval($meetingIsRunningInfo['running']) == 'true' |
395
|
|
|
) { |
396
|
|
|
$meetingInfoExists = true; |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
if ($this->debug) { |
400
|
|
|
error_log( |
401
|
|
|
"meeting is running: " . intval($meetingInfoExists) |
402
|
|
|
); |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
if ($meetingInfoExists) { |
406
|
|
|
$status = true; |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
if ($loop) { |
410
|
|
|
continue; |
411
|
|
|
} else { |
412
|
|
|
break; |
413
|
|
|
} |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
if ($meetingInfoExists) { |
417
|
|
|
$joinParams = array( |
418
|
|
|
'meetingId' => $meetingData['remote_id'], // -- REQUIRED - A unique id for the meeting |
419
|
|
|
'username' => $this->userCompleteName, //-- REQUIRED - The name that will display for the user in the meeting |
420
|
|
|
'password' => $pass, //-- REQUIRED - The attendee or moderator password, depending on what's passed here |
421
|
|
|
//'createTime' => api_get_utc_datetime(), //-- OPTIONAL - string. Leave blank ('') unless you set this correctly. |
422
|
|
|
'userID' => api_get_user_id(), //-- OPTIONAL - string |
423
|
|
|
'webVoiceConf' => '' // -- OPTIONAL - string |
424
|
|
|
); |
425
|
|
|
$url = $this->api->getJoinMeetingURL($joinParams); |
426
|
|
|
$url = $this->protocol.$url; |
427
|
|
|
} else { |
428
|
|
|
$url = $this->logoutUrl; |
429
|
|
|
} |
430
|
|
|
if ($this->debug) { |
431
|
|
|
error_log("return url :" . $url); |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
return $url; |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* Get information about the given meeting |
439
|
|
|
* @param array ...? |
440
|
|
|
* @return mixed Array of information on success, false on error |
441
|
|
|
* @assert (array()) === false |
442
|
|
|
*/ |
443
|
|
|
public function getMeetingInfo($params) |
444
|
|
|
{ |
445
|
|
|
try { |
446
|
|
|
$result = $this->api->getMeetingInfoWithXmlResponseArray($params); |
447
|
|
|
if ($result == null) { |
448
|
|
|
if ($this->debug) { |
449
|
|
|
error_log("Failed to get any response. Maybe we can't contact the BBB server."); |
450
|
|
|
} |
451
|
|
|
} else { |
452
|
|
|
return $result; |
453
|
|
|
} |
454
|
|
|
} catch (Exception $e) { |
455
|
|
|
if ($this->debug) { |
456
|
|
|
error_log('Caught exception: ', $e->getMessage(), "\n"); |
457
|
|
|
} |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
return false; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
/** |
464
|
|
|
* Gets all the course meetings saved in the plugin_bbb_meeting table |
465
|
|
|
* @return array Array of current open meeting rooms |
466
|
|
|
*/ |
467
|
|
|
public function getMeetings($courseId = 0, $sessionId = 0, $groupId = 0) |
468
|
|
|
{ |
469
|
|
|
$em = Database::getManager(); |
470
|
|
|
$pass = $this->getUserMeetingPassword(); |
471
|
|
|
$conditions = []; |
472
|
|
|
|
473
|
|
|
if ($courseId || $sessionId || $groupId) { |
474
|
|
|
$conditions = array( |
475
|
|
|
'where' => array( |
476
|
|
|
'c_id = ? AND session_id = ? ' => array($courseId, $sessionId), |
477
|
|
|
), |
478
|
|
|
); |
479
|
|
|
|
480
|
|
View Code Duplication |
if ($this->hasGroupSupport()) { |
481
|
|
|
$conditions = array( |
482
|
|
|
'where' => array( |
483
|
|
|
'c_id = ? AND session_id = ? AND group_id = ? ' => array($courseId, $sessionId, $groupId) |
484
|
|
|
) |
485
|
|
|
); |
486
|
|
|
} |
487
|
|
|
} |
488
|
|
|
|
489
|
|
|
$meetingList = Database::select( |
490
|
|
|
'*', |
491
|
|
|
$this->table, |
492
|
|
|
$conditions |
493
|
|
|
); |
494
|
|
|
$isGlobal = $this->isGlobalConference(); |
495
|
|
|
$newMeetingList = array(); |
496
|
|
|
$item = array(); |
497
|
|
|
foreach ($meetingList as $meetingDB) { |
498
|
|
|
$meetingBBB = $this->getMeetingInfo(['meetingId' => $meetingDB['remote_id'], 'password' => $pass]); |
499
|
|
View Code Duplication |
if ($meetingBBB === false) { |
500
|
|
|
//checking with the remote_id didn't work, so just in case and |
501
|
|
|
// to provide backwards support, check with the id |
502
|
|
|
$params = array( |
503
|
|
|
'meetingId' => $meetingDB['id'], |
504
|
|
|
// -- REQUIRED - The unique id for the meeting |
505
|
|
|
'password' => $pass |
506
|
|
|
// -- REQUIRED - The moderator password for the meeting |
507
|
|
|
); |
508
|
|
|
$meetingBBB = $this->getMeetingInfo($params); |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
if ($meetingDB['visibility'] == 0 && $this->isConferenceManager() === false) { |
512
|
|
|
continue; |
513
|
|
|
} |
514
|
|
|
$meetingBBB['end_url'] = $this->endUrl($meetingDB); |
515
|
|
|
|
516
|
|
|
if ((string)$meetingBBB['returncode'] == 'FAILED') { |
517
|
|
|
if ($meetingDB['status'] == 1 && $this->isConferenceManager()) { |
518
|
|
|
$this->endMeeting($meetingDB['id']); |
519
|
|
|
} |
520
|
|
|
} else { |
521
|
|
|
$meetingBBB['add_to_calendar_url'] = $this->addToCalendarUrl($meetingDB); |
522
|
|
|
} |
523
|
|
|
|
524
|
|
|
$recordArray = array(); |
525
|
|
|
$actionLinksArray = array(); |
526
|
|
|
|
527
|
|
|
if ($meetingDB['record'] == 1) { |
528
|
|
|
// backwards compatibility (when there was no remote ID) |
529
|
|
|
$mId = $meetingDB['remote_id']; |
530
|
|
|
if (empty($mId)) { |
531
|
|
|
$mId = $meetingDB['id']; |
532
|
|
|
} |
533
|
|
|
if (empty($mId)) { |
534
|
|
|
// if the id is still empty (should *never* occur as 'id' is |
535
|
|
|
// the table's primary key), skip this conference |
536
|
|
|
continue; |
537
|
|
|
} |
538
|
|
|
$recordingParams = array( |
539
|
|
|
'meetingId' => $mId, //-- OPTIONAL - comma separate if multiple ids |
540
|
|
|
); |
541
|
|
|
|
542
|
|
|
//To see the recording list in your BBB server do: bbb-record --list |
543
|
|
|
$records = $this->api->getRecordingsWithXmlResponseArray($recordingParams); |
544
|
|
|
if (!empty($records)) { |
545
|
|
|
$count = 1; |
546
|
|
|
if (isset($records['message']) && !empty($records['message'])) { |
547
|
|
|
if ($records['messageKey'] == 'noRecordings') { |
548
|
|
|
$recordArray[] = get_lang('NoRecording'); |
549
|
|
|
if ($meetingDB['visibility'] == 0) { |
550
|
|
|
$actionLinksArray[] = Display::url( |
551
|
|
|
Display::return_icon( |
552
|
|
|
'invisible.png', |
553
|
|
|
get_lang('MakeVisible'), |
554
|
|
|
array(), |
555
|
|
|
ICON_SIZE_MEDIUM |
556
|
|
|
), |
557
|
|
|
$this->publishUrl($meetingDB) |
558
|
|
|
); |
559
|
|
|
} else { |
560
|
|
|
$actionLinksArray[] = Display::url( |
561
|
|
|
Display::return_icon( |
562
|
|
|
'visible.png', |
563
|
|
|
get_lang('MakeInvisible'), |
564
|
|
|
array(), |
565
|
|
|
ICON_SIZE_MEDIUM |
566
|
|
|
), |
567
|
|
|
$this->unPublishUrl($meetingDB) |
568
|
|
|
); |
569
|
|
|
} |
570
|
|
|
} |
571
|
|
|
} else { |
572
|
|
|
foreach ($records as $record) { |
573
|
|
|
//if you get several recordings here and you used a |
574
|
|
|
// previous version of Chamilo, you might want to |
575
|
|
|
// only keep the last result for each chamilo conf |
576
|
|
|
// (see show_links after the end of this loop) |
577
|
|
|
if (is_array($record) && isset($record['recordId'])) { |
578
|
|
|
$url = Display::url( |
579
|
|
|
get_lang('ViewRecord')." [~".$record['playbackFormatLength']."']", |
580
|
|
|
$record['playbackFormatUrl'], |
581
|
|
|
array('target' => '_blank') |
582
|
|
|
); |
583
|
|
|
$actionLinks = ''; |
584
|
|
|
if ($this->isConferenceManager()) { |
585
|
|
|
if ($isGlobal === false) { |
586
|
|
|
$actionLinks .= Display::url( |
587
|
|
|
Display::return_icon( |
588
|
|
|
'link.gif', |
589
|
|
|
get_lang('CopyToLinkTool') |
590
|
|
|
), |
591
|
|
|
$this->copyToRecordToLinkTool($meetingDB) |
592
|
|
|
); |
593
|
|
|
$actionLinks .= Display::url( |
594
|
|
|
Display::return_icon( |
595
|
|
|
'agenda.png', |
596
|
|
|
get_lang('AddToCalendar') |
597
|
|
|
), |
598
|
|
|
$this->addToCalendarUrl($meetingDB, $record) |
599
|
|
|
); |
600
|
|
|
} |
601
|
|
|
$actionLinks .= Display::url( |
602
|
|
|
Display::return_icon( |
603
|
|
|
'delete.png', |
604
|
|
|
get_lang('Delete') |
605
|
|
|
), |
606
|
|
|
$this->deleteRecordUrl($meetingDB) |
607
|
|
|
); |
608
|
|
|
|
609
|
|
View Code Duplication |
if ($meetingDB['visibility'] == 0) { |
610
|
|
|
$actionLinks .= Display::url( |
611
|
|
|
Display::return_icon( |
612
|
|
|
'invisible.png', |
613
|
|
|
get_lang('MakeVisible'), |
614
|
|
|
array(), |
615
|
|
|
ICON_SIZE_MEDIUM |
616
|
|
|
), |
617
|
|
|
$this->publishUrl($meetingDB) |
618
|
|
|
); |
619
|
|
|
} else { |
620
|
|
|
$actionLinks .= Display::url( |
621
|
|
|
Display::return_icon( |
622
|
|
|
'visible.png', |
623
|
|
|
get_lang('MakeInvisible'), |
624
|
|
|
array(), |
625
|
|
|
ICON_SIZE_MEDIUM |
626
|
|
|
), |
627
|
|
|
$this->unPublishUrl($meetingDB) |
628
|
|
|
); |
629
|
|
|
} |
630
|
|
|
} |
631
|
|
|
$count++; |
632
|
|
|
$recordArray[] = $url; |
633
|
|
|
$actionLinksArray[] = $actionLinks; |
634
|
|
|
} else { |
|
|
|
|
635
|
|
|
/*if (is_array($record) && isset($record['recordID']) && isset($record['playbacks'])) { |
636
|
|
|
|
637
|
|
|
//Fix the bbb timestamp |
638
|
|
|
//$record['startTime'] = substr($record['startTime'], 0, strlen($record['startTime']) -3); |
639
|
|
|
//$record['endTime'] = substr($record['endTime'], 0, strlen($record['endTime']) -3); |
640
|
|
|
//.' - '.api_convert_and_format_date($record['startTime']).' - '.api_convert_and_format_date($record['endTime']) |
641
|
|
|
foreach($record['playbacks'] as $item) { |
642
|
|
|
$url = Display::url(get_lang('ViewRecord'), $item['url'], array('target' => '_blank')); |
643
|
|
|
//$url .= Display::url(get_lang('DeleteRecord'), api_get_self().'?action=delete_record&'.$record['recordID']); |
644
|
|
|
if ($this->isConferenceManager()) { |
645
|
|
|
$url .= Display::url(Display::return_icon('link.gif',get_lang('CopyToLinkTool')), api_get_self().'?action=copy_record_to_link_tool&id='.$meetingDB['id'].'&record_id='.$record['recordID']); |
646
|
|
|
$url .= Display::url(Display::return_icon('agenda.png',get_lang('AddToCalendar')), api_get_self().'?action=add_to_calendar&id='.$meetingDB['id'].'&start='.api_strtotime($meetingDB['created_at']).'&url='.$item['url']); |
647
|
|
|
$url .= Display::url(Display::return_icon('delete.png',get_lang('Delete')), api_get_self().'?action=delete_record&id='.$record['recordID']); |
648
|
|
|
} |
649
|
|
|
//$url .= api_get_self().'?action=publish&id='.$record['recordID']; |
650
|
|
|
$count++; |
651
|
|
|
$recordArray[] = $url; |
652
|
|
|
} |
653
|
|
|
}*/ |
654
|
|
|
} |
655
|
|
|
} |
656
|
|
|
} |
657
|
|
|
} else { |
658
|
|
|
$actionLinks = ''; |
659
|
|
View Code Duplication |
if ($this->isConferenceManager()) { |
660
|
|
|
if ($meetingDB['visibility'] == 0) { |
661
|
|
|
$actionLinks .= Display::url( |
662
|
|
|
Display::return_icon( |
663
|
|
|
'invisible.png', |
664
|
|
|
get_lang('MakeVisible'), |
665
|
|
|
array(), |
666
|
|
|
ICON_SIZE_MEDIUM |
667
|
|
|
), |
668
|
|
|
$this->publishUrl($meetingDB) |
669
|
|
|
); |
670
|
|
|
} else { |
671
|
|
|
$actionLinks .= Display::url( |
672
|
|
|
Display::return_icon( |
673
|
|
|
'visible.png', |
674
|
|
|
get_lang('MakeInvisible'), |
675
|
|
|
array(), |
676
|
|
|
ICON_SIZE_MEDIUM |
677
|
|
|
), |
678
|
|
|
$this->unPublishUrl($meetingDB) |
679
|
|
|
); |
680
|
|
|
} |
681
|
|
|
} |
682
|
|
|
$actionLinksArray[] = $actionLinks; |
683
|
|
|
$item['action_links'] = implode('<br />', $actionLinksArray); |
684
|
|
|
} |
685
|
|
|
//var_dump($recordArray); |
686
|
|
|
$item['show_links'] = implode('<br />', $recordArray); |
687
|
|
|
$item['action_links'] = implode('<br />', $actionLinksArray); |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
$item['created_at'] = api_convert_and_format_date($meetingDB['created_at']); |
691
|
|
|
//created_at |
692
|
|
|
$meetingDB['created_at'] = $item['created_at']; //avoid overwrite in array_merge() below |
693
|
|
|
|
694
|
|
|
$item['publish_url'] = $this->publishUrl($meetingDB); |
695
|
|
|
$item['unpublish_url'] = $this->unPublishUrl($meetingBBB); |
|
|
|
|
696
|
|
|
|
697
|
|
|
if ($meetingDB['status'] == 1) { |
698
|
|
|
$joinParams = array( |
699
|
|
|
'meetingId' => $meetingDB['remote_id'], //-- REQUIRED - A unique id for the meeting |
700
|
|
|
'username' => $this->userCompleteName, //-- REQUIRED - The name that will display for the user in the meeting |
701
|
|
|
'password' => $pass, //-- REQUIRED - The attendee or moderator password, depending on what's passed here |
702
|
|
|
'createTime' => '', //-- OPTIONAL - string. Leave blank ('') unless you set this correctly. |
703
|
|
|
'userID' => '', // -- OPTIONAL - string |
704
|
|
|
'webVoiceConf' => '' // -- OPTIONAL - string |
705
|
|
|
); |
706
|
|
|
$item['go_url'] = $this->protocol.$this->api->getJoinMeetingURL($joinParams); |
707
|
|
|
} |
708
|
|
|
$item = array_merge($item, $meetingDB, $meetingBBB); |
709
|
|
|
|
710
|
|
|
$item['course'] = $em->find('ChamiloCoreBundle:Course', $item['c_id']); |
711
|
|
|
$item['session'] = $em->find('ChamiloCoreBundle:Session', $item['session_id']); |
712
|
|
|
|
713
|
|
|
$newMeetingList[] = $item; |
714
|
|
|
} |
715
|
|
|
|
716
|
|
|
return $newMeetingList; |
717
|
|
|
} |
718
|
|
|
|
719
|
|
|
/** |
720
|
|
|
* Function disabled |
721
|
|
|
*/ |
722
|
|
View Code Duplication |
public function publishMeeting($id) |
723
|
|
|
{ |
724
|
|
|
//return BigBlueButtonBN::setPublishRecordings($id, 'true', $this->url, $this->salt); |
725
|
|
|
if (empty($id)) { |
726
|
|
|
|
727
|
|
|
return false; |
728
|
|
|
} |
729
|
|
|
$id = intval($id); |
730
|
|
|
Database::update($this->table, array('visibility' => 1), array('id = ? ' => $id)); |
731
|
|
|
|
732
|
|
|
return true; |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
/** |
736
|
|
|
* Function disabled |
737
|
|
|
*/ |
738
|
|
View Code Duplication |
public function unpublishMeeting($id) |
739
|
|
|
{ |
740
|
|
|
//return BigBlueButtonBN::setPublishRecordings($id, 'false', $this->url, $this->salt); |
741
|
|
|
if (empty($id)) { |
742
|
|
|
|
743
|
|
|
return false; |
744
|
|
|
} |
745
|
|
|
$id = intval($id); |
746
|
|
|
Database::update($this->table, array('visibility' => 0), array('id = ?' => $id)); |
747
|
|
|
|
748
|
|
|
return true; |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
/** |
752
|
|
|
* Closes a meeting (usually when the user click on the close button from |
753
|
|
|
* the conferences listing. |
754
|
|
|
* @param string The internal ID of the meeting (id field for this meeting) |
755
|
|
|
* @return void |
756
|
|
|
* @assert (0) === false |
757
|
|
|
*/ |
758
|
|
|
public function endMeeting($id) |
759
|
|
|
{ |
760
|
|
|
if (empty($id)) { |
761
|
|
|
|
762
|
|
|
return false; |
763
|
|
|
} |
764
|
|
|
$meetingData = Database::select('*', $this->table, array('where' => array('id = ?' => array($id))), 'first'); |
765
|
|
|
$pass = $this->getUserMeetingPassword(); |
766
|
|
|
|
767
|
|
|
$endParams = array( |
768
|
|
|
'meetingId' => $meetingData['remote_id'], // REQUIRED - We have to know which meeting to end. |
769
|
|
|
'password' => $pass, // REQUIRED - Must match moderator pass for meeting. |
770
|
|
|
); |
771
|
|
|
$this->api->endMeetingWithXmlResponseArray($endParams); |
772
|
|
|
Database::update( |
773
|
|
|
$this->table, |
774
|
|
|
array('status' => 0, 'closed_at' => api_get_utc_datetime()), |
775
|
|
|
array('id = ? ' => $id) |
776
|
|
|
); |
777
|
|
|
} |
778
|
|
|
|
779
|
|
|
/** |
780
|
|
|
* Gets the password for a specific meeting for the current user |
781
|
|
|
* @return string A moderator password if user is teacher, or the course code otherwise |
782
|
|
|
*/ |
783
|
|
|
public function getUserMeetingPassword() |
784
|
|
|
{ |
785
|
|
|
if ($this->isConferenceManager()) { |
786
|
|
|
|
787
|
|
|
return $this->getModMeetingPassword(); |
788
|
|
|
} else { |
789
|
|
|
|
790
|
|
|
if ($this->isGlobalConference()) { |
791
|
|
|
|
792
|
|
|
return 'url_'.api_get_current_access_url_id(); |
793
|
|
|
} |
794
|
|
|
|
795
|
|
|
return api_get_course_id(); |
796
|
|
|
} |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
/** |
800
|
|
|
* Generated a moderator password for the meeting |
801
|
|
|
* @return string A password for the moderation of the videoconference |
802
|
|
|
*/ |
803
|
|
|
public function getModMeetingPassword() |
804
|
|
|
{ |
805
|
|
|
if ($this->isGlobalConference()) { |
806
|
|
|
|
807
|
|
|
return 'url_'.api_get_current_access_url_id().'_mod'; |
808
|
|
|
} |
809
|
|
|
|
810
|
|
|
return api_get_course_id().'mod'; |
811
|
|
|
} |
812
|
|
|
|
813
|
|
|
/** |
814
|
|
|
* Get users online in the current course room |
815
|
|
|
* @return int The number of users currently connected to the videoconference |
816
|
|
|
* @assert () > -1 |
817
|
|
|
*/ |
818
|
|
|
public function getUsersOnlineInCurrentRoom() |
819
|
|
|
{ |
820
|
|
|
$courseId = api_get_course_int_id(); |
821
|
|
|
$sessionId = api_get_session_id(); |
822
|
|
|
|
823
|
|
|
$conditions = array( |
824
|
|
|
'where' => array( |
825
|
|
|
'c_id = ? AND session_id = ? AND status = 1 ' => array( |
826
|
|
|
$courseId, |
827
|
|
|
$sessionId, |
828
|
|
|
), |
829
|
|
|
), |
830
|
|
|
); |
831
|
|
|
|
832
|
|
View Code Duplication |
if ($this->hasGroupSupport()) { |
833
|
|
|
$groupId = api_get_group_id(); |
834
|
|
|
$conditions = array( |
835
|
|
|
'where' => array( |
836
|
|
|
'c_id = ? AND session_id = ? AND group_id = ? AND status = 1 ' => array( |
837
|
|
|
$courseId, |
838
|
|
|
$sessionId, |
839
|
|
|
$groupId |
840
|
|
|
), |
841
|
|
|
), |
842
|
|
|
); |
843
|
|
|
} |
844
|
|
|
$meetingData = Database::select( |
845
|
|
|
'*', |
846
|
|
|
$this->table, |
847
|
|
|
$conditions, |
848
|
|
|
'first' |
849
|
|
|
); |
850
|
|
|
|
851
|
|
|
if (empty($meetingData)) { |
852
|
|
|
return 0; |
853
|
|
|
} |
854
|
|
|
$pass = $this->getModMeetingPassword(); |
855
|
|
|
$info = $this->getMeetingInfo(array('meetingId' => $meetingData['remote_id'], 'password' => $pass)); |
856
|
|
View Code Duplication |
if ($info === false) { |
857
|
|
|
//checking with the remote_id didn't work, so just in case and |
858
|
|
|
// to provide backwards support, check with the id |
859
|
|
|
$params = array( |
860
|
|
|
'meetingId' => $meetingData['id'], |
861
|
|
|
// -- REQUIRED - The unique id for the meeting |
862
|
|
|
'password' => $pass |
863
|
|
|
// -- REQUIRED - The moderator password for the meeting |
864
|
|
|
); |
865
|
|
|
$info = $this->getMeetingInfo($params); |
866
|
|
|
} |
867
|
|
|
|
868
|
|
|
if (!empty($info) && isset($info['participantCount'])) { |
869
|
|
|
return $info['participantCount']; |
870
|
|
|
|
871
|
|
|
} |
872
|
|
|
return 0; |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
/** |
876
|
|
|
* Deletes a previous recording of a meeting |
877
|
|
|
* @param int integral ID of the recording |
878
|
|
|
* @return array ? |
879
|
|
|
* @assert () === false |
880
|
|
|
* @todo Also delete links and agenda items created from this recording |
881
|
|
|
*/ |
882
|
|
|
public function deleteRecord($id) |
883
|
|
|
{ |
884
|
|
|
if (empty($id)) { |
885
|
|
|
return false; |
886
|
|
|
} |
887
|
|
|
|
888
|
|
|
$meetingData = Database::select( |
889
|
|
|
'*', |
890
|
|
|
$this->table, |
891
|
|
|
array('where' => array('id = ?' => array($id))), |
892
|
|
|
'first' |
893
|
|
|
); |
894
|
|
|
|
895
|
|
|
$recordingParams = array( |
896
|
|
|
/* |
897
|
|
|
* NOTE: Set the recordId below to a valid id after you have |
898
|
|
|
* created a recorded meeting, and received a real recordID |
899
|
|
|
* back from your BBB server using the |
900
|
|
|
* getRecordingsWithXmlResponseArray method. |
901
|
|
|
*/ |
902
|
|
|
|
903
|
|
|
// REQUIRED - We have to know which recording: |
904
|
|
|
'recordId' => $meetingData['remote_id'], |
905
|
|
|
); |
906
|
|
|
|
907
|
|
|
$result = $this->api->deleteRecordingsWithXmlResponseArray($recordingParams); |
908
|
|
|
|
909
|
|
|
if (!empty($result) && isset($result['deleted']) && $result['deleted'] == 'true') { |
910
|
|
|
Database::delete( |
911
|
|
|
$this->table, |
912
|
|
|
array('id = ?' => array($id)) |
913
|
|
|
); |
914
|
|
|
} |
915
|
|
|
|
916
|
|
|
return $result; |
917
|
|
|
} |
918
|
|
|
|
919
|
|
|
/** |
920
|
|
|
* Creates a link in the links tool from the given videoconference recording |
921
|
|
|
* @param int ID of the item in the plugin_bbb_meeting table |
922
|
|
|
* @param string Hash identifying the recording, as provided by the API |
923
|
|
|
* @return mixed ID of the newly created link, or false on error |
924
|
|
|
* @assert (null, null) === false |
925
|
|
|
* @assert (1, null) === false |
926
|
|
|
* @assert (null, 'abcdefabcdefabcdefabcdef') === false |
927
|
|
|
*/ |
928
|
|
|
public function copyRecordToLinkTool($id) |
929
|
|
|
{ |
930
|
|
|
if (empty($id)) { |
931
|
|
|
return false; |
932
|
|
|
} |
933
|
|
|
//$records = BigBlueButtonBN::getRecordingsUrl($id); |
934
|
|
|
$meetingData = Database::select('*', $this->table, array('where' => array('id = ?' => array($id))), 'first'); |
935
|
|
|
|
936
|
|
|
$records = $this->api->getRecordingsWithXmlResponseArray(array('meetingId' => $meetingData['remote_id'])); |
937
|
|
|
|
938
|
|
|
if (!empty($records)) { |
939
|
|
|
if (isset($records['message']) && !empty($records['message'])) { |
940
|
|
|
if ($records['messageKey'] == 'noRecordings') { |
941
|
|
|
$recordArray[] = get_lang('NoRecording'); |
942
|
|
|
} else { |
|
|
|
|
943
|
|
|
//$recordArray[] = $records['message']; |
944
|
|
|
} |
945
|
|
|
return false; |
946
|
|
|
} else { |
947
|
|
|
$record = $records[0]; |
948
|
|
|
if (is_array($record) && isset($record['recordId'])) { |
949
|
|
|
$url = $record['playbackFormatUrl']; |
950
|
|
|
$link = new Link(); |
|
|
|
|
951
|
|
|
$params['url'] = $url; |
952
|
|
|
$params['title'] = $meetingData['meeting_name']; |
953
|
|
|
$id = $link->save($params); |
954
|
|
|
return $id; |
955
|
|
|
} |
956
|
|
|
} |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
return false; |
960
|
|
|
} |
961
|
|
|
|
962
|
|
|
/** |
963
|
|
|
* Checks if the video conference server is running. |
964
|
|
|
* Function currently disabled (always returns 1) |
965
|
|
|
* @return bool True if server is running, false otherwise |
966
|
|
|
* @assert () === false |
967
|
|
|
*/ |
968
|
|
|
public function isServerRunning() |
969
|
|
|
{ |
970
|
|
|
return true; |
971
|
|
|
//return BigBlueButtonBN::isServerRunning($this->protocol.$this->url); |
972
|
|
|
} |
973
|
|
|
|
974
|
|
|
/** |
975
|
|
|
* Get active session in the all platform |
976
|
|
|
*/ |
977
|
|
|
public function getActiveSessionsCount() |
978
|
|
|
{ |
979
|
|
|
$meetingList = Database::select( |
980
|
|
|
'count(id) as count', |
981
|
|
|
$this->table, |
982
|
|
|
array('where' => array('status = ?' => array(1))), |
983
|
|
|
'first' |
984
|
|
|
); |
985
|
|
|
|
986
|
|
|
return $meetingList['count']; |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
/** |
990
|
|
|
* @param string $url |
991
|
|
|
*/ |
992
|
|
|
public function redirectToBBB($url) |
993
|
|
|
{ |
994
|
|
|
if (file_exists(__DIR__ . '/../config.vm.php')) { |
995
|
|
|
// Using VM |
996
|
|
|
echo Display::url(get_lang('ClickToContinue'), $url); |
997
|
|
|
exit; |
998
|
|
|
} else { |
999
|
|
|
// Classic |
1000
|
|
|
header("Location: $url"); |
1001
|
|
|
exit; |
1002
|
|
|
} |
1003
|
|
|
} |
1004
|
|
|
|
1005
|
|
|
/** |
1006
|
|
|
* @return string |
1007
|
|
|
*/ |
1008
|
|
|
public function getUrlParams() |
1009
|
|
|
{ |
1010
|
|
|
$courseInfo = api_get_course_info(); |
1011
|
|
|
|
1012
|
|
|
if (empty($courseInfo)) { |
1013
|
|
|
|
1014
|
|
|
if ($this->isGlobalConference()) { |
1015
|
|
|
return 'global=1'; |
1016
|
|
|
} |
1017
|
|
|
|
1018
|
|
|
return ''; |
1019
|
|
|
} |
1020
|
|
|
|
1021
|
|
|
return api_get_cidreq(); |
1022
|
|
|
} |
1023
|
|
|
|
1024
|
|
|
/** |
1025
|
|
|
* @return string |
1026
|
|
|
*/ |
1027
|
|
|
public function getCurrentVideoConferenceName() |
1028
|
|
|
{ |
1029
|
|
|
if ($this->isGlobalConference()) { |
1030
|
|
|
return 'url_'.api_get_current_access_url_id(); |
1031
|
|
|
} |
1032
|
|
|
|
1033
|
|
|
if ($this->hasGroupSupport()) { |
1034
|
|
|
|
1035
|
|
|
return api_get_course_id().'-'.api_get_session_id().'-'.api_get_group_id(); |
1036
|
|
|
} |
1037
|
|
|
|
1038
|
|
|
return api_get_course_id().'-'.api_get_session_id(); |
1039
|
|
|
} |
1040
|
|
|
|
1041
|
|
|
/** |
1042
|
|
|
* @return string |
1043
|
|
|
*/ |
1044
|
|
|
public function getConferenceUrl() |
1045
|
|
|
{ |
1046
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/start.php?launch=1&'.$this->getUrlParams(); |
1047
|
|
|
} |
1048
|
|
|
|
1049
|
|
|
/** |
1050
|
|
|
* @return string |
1051
|
|
|
*/ |
1052
|
|
|
public function getListingUrl() |
1053
|
|
|
{ |
1054
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams(); |
1055
|
|
|
} |
1056
|
|
|
|
1057
|
|
|
/** |
1058
|
|
|
* @param array $meeting |
1059
|
|
|
* @return string |
1060
|
|
|
*/ |
1061
|
|
|
public function endUrl($meeting) |
1062
|
|
|
{ |
1063
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=end&id='.$meeting['id']; |
1064
|
|
|
} |
1065
|
|
|
|
1066
|
|
|
/** |
1067
|
|
|
* @param array $meeting |
1068
|
|
|
* @param array $record |
1069
|
|
|
* @return string |
1070
|
|
|
*/ |
1071
|
|
|
public function addToCalendarUrl($meeting, $record = []) |
1072
|
|
|
{ |
1073
|
|
|
$url = isset($record['playbackFormatUrl']) ? $record['playbackFormatUrl'] : ''; |
1074
|
|
|
|
1075
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=add_to_calendar&id='.$meeting['id'].'&start='.api_strtotime($meeting['created_at']).'&url='.$url; |
1076
|
|
|
} |
1077
|
|
|
|
1078
|
|
|
/** |
1079
|
|
|
* @param array $meeting |
1080
|
|
|
* @return string |
1081
|
|
|
*/ |
1082
|
|
|
public function publishUrl($meeting) |
1083
|
|
|
{ |
1084
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=publish&id='.$meeting['id']; |
1085
|
|
|
} |
1086
|
|
|
|
1087
|
|
|
/** |
1088
|
|
|
* @param array $meeting |
1089
|
|
|
* @return string |
1090
|
|
|
*/ |
1091
|
|
|
public function unPublishUrl($meeting) |
1092
|
|
|
{ |
1093
|
|
|
if (!isset($meeting['id'])) { |
1094
|
|
|
return null; |
1095
|
|
|
} |
1096
|
|
|
|
1097
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=unpublish&id='.$meeting['id']; |
1098
|
|
|
} |
1099
|
|
|
|
1100
|
|
|
/** |
1101
|
|
|
* @param array $meeting |
1102
|
|
|
* @return string |
1103
|
|
|
*/ |
1104
|
|
|
public function deleteRecordUrl($meeting) |
1105
|
|
|
{ |
1106
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=delete_record&id='.$meeting['id']; |
1107
|
|
|
} |
1108
|
|
|
|
1109
|
|
|
/** |
1110
|
|
|
* @param array $meeting |
1111
|
|
|
* @return string |
1112
|
|
|
*/ |
1113
|
|
|
public function copyToRecordToLinkTool($meeting) |
1114
|
|
|
{ |
1115
|
|
|
return api_get_path(WEB_PLUGIN_PATH).'bbb/listing.php?'.$this->getUrlParams().'&action=copy_record_to_link_tool&id='.$meeting['id']; |
1116
|
|
|
} |
1117
|
|
|
|
1118
|
|
|
/** |
1119
|
|
|
* Get the meeting info from DB by its name |
1120
|
|
|
* @param string $name |
1121
|
|
|
* @return array |
1122
|
|
|
*/ |
1123
|
|
|
public function findMeetingByName($name) |
1124
|
|
|
{ |
1125
|
|
|
$meetingData = Database::select( |
1126
|
|
|
'*', |
1127
|
|
|
'plugin_bbb_meeting', |
1128
|
|
|
array('where' => array('meeting_name = ? AND status = 1 ' => $name)), |
1129
|
|
|
'first' |
1130
|
|
|
); |
1131
|
|
|
|
1132
|
|
|
return $meetingData; |
1133
|
|
|
} |
1134
|
|
|
|
1135
|
|
|
/** |
1136
|
|
|
* @param int $meetingId |
1137
|
|
|
* @return array |
1138
|
|
|
*/ |
1139
|
|
|
public function findMeetingParticipants($meetingId) |
1140
|
|
|
{ |
1141
|
|
|
$em = Database::getManager(); |
1142
|
|
|
$meetingData = Database::select( |
1143
|
|
|
'*', |
1144
|
|
|
'plugin_bbb_room', |
1145
|
|
|
array('where' => array('meeting_id = ?' => intval($meetingId))) |
1146
|
|
|
); |
1147
|
|
|
|
1148
|
|
|
$return = []; |
1149
|
|
|
|
1150
|
|
|
foreach ($meetingData as $participantInfo) { |
1151
|
|
|
$return[] = [ |
1152
|
|
|
'id' => $participantInfo['id'], |
1153
|
|
|
'meeting_id' => $participantInfo['meeting_id'], |
1154
|
|
|
'participant' => $em->find('ChamiloUserBundle:User', $participantInfo['participant_id']), |
1155
|
|
|
'in_at' => $participantInfo['in_at'], |
1156
|
|
|
'out_at' => $participantInfo['out_at'] |
1157
|
|
|
]; |
1158
|
|
|
} |
1159
|
|
|
|
1160
|
|
|
return $return; |
1161
|
|
|
} |
1162
|
|
|
} |
1163
|
|
|
|
This check looks for the
else
branches ofif
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
else
branches can be removed.could be turned into
This is much more concise to read.