Completed
Pull Request — master (#155)
by Jesus
01:57
created

brokerlib.php ➔ bigbluebuttonbn_broker_meeting_events()   B

Complexity

Conditions 6
Paths 11

Size

Total Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 11
nop 1
dl 0
loc 53
rs 8.4032
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
 * Broker helper methods.
19
 *
20
 * @package   mod_bigbluebuttonbn
21
 * @copyright 2010 onwards, Blindside Networks Inc
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
24
 * @author    Fred Dixon  (ffdixon [at] blindsidenetworks [dt] com)
25
 * @author    Darko Miletic  (darko.miletic [at] gmail [dt] com)
26
 */
27
28
defined('MOODLE_INTERNAL') || die();
29
30
/**
31
 * Callback for meeting info.
32
 *
33
 * @param array $bbbsession
34
 * @param array $params
35
 * @param boolean $updatecache
36
 *
37
 * @return string
38
 */
39
function bigbluebuttonbn_broker_meeting_info($bbbsession, $params, $updatecache) {
40
    $callbackresponse = array();
41
    $info = bigbluebuttonbn_get_meeting_info($params['id'], $updatecache);
42
    $callbackresponse['info'] = $info;
43
    $running = false;
44
    if ($info['returncode'] == 'SUCCESS') {
45
        $running = ($info['running'] === 'true');
46
    }
47
    $callbackresponse['running'] = $running;
48
    $status = array();
49
    $status["join_url"] = $bbbsession['joinURL'];
50
    $status["join_button_text"] = get_string('view_conference_action_join', 'bigbluebuttonbn');
51
    $status["end_button_text"] = get_string('view_conference_action_end', 'bigbluebuttonbn');
52
    $participantcount = 0;
53
    if (isset($info['participantCount'])) {
54
        $participantcount = $info['participantCount'];
55
    }
56
    $canjoin = bigbluebuttonbn_broker_meeting_info_can_join($bbbsession, $running, $participantcount);
57
    $status["can_join"] = $canjoin["can_join"];
58
    $status["message"] = $canjoin["message"];
59
    $canend = bigbluebuttonbn_broker_meeting_info_can_end($bbbsession, $running);
60
    $status["can_end"] = $canend["can_end"];
61
    $callbackresponse['status'] = $status;
62
    $callbackresponsedata = json_encode($callbackresponse);
63
    return "{$params['callback']}({$callbackresponsedata});";
64
}
65
66
/**
67
 * Helper for evaluating if meeting can be joined, it is used by meeting info callback.
68
 *
69
 * @param array $bbbsession
70
 * @param boolean $running
71
 * @param boolean $participantcount
72
 *
73
 * @return array
74
 */
75
function bigbluebuttonbn_broker_meeting_info_can_join($bbbsession, $running, $participantcount) {
76
    $status = array("can_join" => false);
77
    if ($running) {
78
        $status["message"] = get_string('view_error_userlimit_reached', 'bigbluebuttonbn');
79 View Code Duplication
        if ($bbbsession['userlimit'] == 0 || $participantcount < $bbbsession['userlimit']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
80
            $status["message"] = get_string('view_message_conference_in_progress', 'bigbluebuttonbn');
81
            $status["can_join"] = true;
82
        }
83
        return $status;
84
    }
85
    // If user is administrator, moderator or if is viewer and no waiting is required.
86
    $status["message"] = get_string('view_message_conference_wait_for_moderator', 'bigbluebuttonbn');
87 View Code Duplication
    if ($bbbsession['administrator'] || $bbbsession['moderator'] || !$bbbsession['wait']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
88
        $status["message"] = get_string('view_message_conference_room_ready', 'bigbluebuttonbn');
89
        $status["can_join"] = true;
90
    }
91
    return $status;
92
}
93
94
/**
95
 * Helper for evaluating if meeting can be ended, it is used by meeting info callback.
96
 *
97
 * @param array $bbbsession
98
 * @param boolean $running
99
 *
100
 * @return boolean
101
 */
102
function bigbluebuttonbn_broker_meeting_info_can_end($bbbsession, $running) {
103
    if ($running && ($bbbsession['administrator'] || $bbbsession['moderator'])) {
104
        return array("can_end" => true);
105
    }
106
    return array("can_end" => false);
107
}
108
109
/**
110
 * Callback for meeting end.
111
 *
112
 * @param array $bbbsession
113
 * @param array $params
114
 *
115
 * @return string
116
 */
117
function bigbluebuttonbn_broker_meeting_end($bbbsession, $params) {
118
    if (!$bbbsession['administrator'] && !$bbbsession['moderator']) {
119
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
120
        return;
121
    }
122
    // Execute the end command.
123
    bigbluebuttonbn_end_meeting($params['id'], $bbbsession['modPW']);
124
    // Moodle event logger: Create an event for meeting ended.
125
    if (isset($bbbsession['bigbluebuttonbn'])) {
126
        bigbluebuttonbn_event_log(\mod_bigbluebuttonbn\event\events::$events['meeting_end'], $bbbsession['bigbluebuttonbn']);
127
    }
128
    // Update the cache.
129
    bigbluebuttonbn_get_meeting_info($params['id'], BIGBLUEBUTTONBN_UPDATE_CACHE);
130
    $callbackresponse = array('status' => true);
131
    $callbackresponsedata = json_encode($callbackresponse);
132
    return "{$params['callback']}({$callbackresponsedata});";
133
}
134
135
/**
136
 * Callback for recording links.
137
 *
138
 * @param array $bbbsession
139
 * @param array $params
140
 *
141
 * @return string
142
 */
143
function bigbluebuttonbn_broker_recording_links($bbbsession, $params) {
144
    if (!$bbbsession['managerecordings']) {
145
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute update command');
146
        return;
147
    }
148
    $callbackresponse = array('status' => false);
149
    if (isset($params['id']) && $params['id'] != '') {
150
        $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
151
        $callbackresponse['status'] = true;
152
        $callbackresponse['links'] = count($importedall);
153
    }
154
    $callbackresponsedata = json_encode($callbackresponse);
155
    return "{$params['callback']}({$callbackresponsedata});";
156
}
157
158
/**
159
 * Callback for recording info.
160
 *
161
 * @param array $bbbsession
162
 * @param array $params
163
 * @param boolean $showroom
164
 *
165
 * @return string
166
 */
167
function bigbluebuttonbn_broker_recording_info($bbbsession, $params, $showroom) {
168
    if (!$bbbsession['managerecordings']) {
169
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute command');
170
        return;
171
    }
172
    $callbackresponse = array('status' => true, 'found' => false);
173
    $courseid = $bbbsession['course']->id;
174
    $bigbluebuttonbnid = null;
175
    if ($showroom) {
176
        $bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
177
    }
178
    $includedeleted = $bbbsession['bigbluebuttonbn']->recordings_deleted;
179
    // Retrieve the array of imported recordings.
180
    $recordings = bigbluebuttonbn_get_allrecordings($courseid, $bigbluebuttonbnid, $showroom, $includedeleted);
181
    if (array_key_exists($params['id'], $recordings)) {
182
        // Look up for an update on the imported recording.
183 View Code Duplication
        if (!array_key_exists('messageKey', $recordings[$params['id']])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
184
            // The recording was found.
185
            $callbackresponse = bigbluebuttonbn_broker_recording_info_current($recordings[$params['id']], $params);
186
        }
187
        $callbackresponsedata = json_encode($callbackresponse);
188
        return "{$params['callback']}({$callbackresponsedata});";
189
    }
190
    // As the recordingid was not identified as imported recording link, look up for a real recording.
191
    $recordings = bigbluebuttonbn_get_recordings_array($params['idx'], $params['id']);
192 View Code Duplication
    if (array_key_exists($params['id'], $recordings)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
193
        // The recording was found.
194
        $callbackresponse = bigbluebuttonbn_broker_recording_info_current($recordings[$params['id']], $params);
195
    }
196
    $callbackresponsedata = json_encode($callbackresponse);
197
    return "{$params['callback']}({$callbackresponsedata});";
198
}
199
200
/**
201
 * Data used as for the callback for recording info.
202
 *
203
 * @param array $recording
204
 * @param array $params
205
 *
206
 * @return string
207
 */
208
function bigbluebuttonbn_broker_recording_info_current($recording, $params) {
209
    $callbackresponse['status'] = true;
210
    $callbackresponse['found'] = true;
211
    $callbackresponse['published'] = (string) $recording['published'];
212
    if (!isset($params['meta']) || empty($params['meta'])) {
213
        return $callbackresponse;
214
    }
215
    $meta = json_decode($params['meta'], true);
216
    foreach (array_keys($meta) as $key) {
217
        $callbackresponse[$key] = '';
218
        if (isset($recording[$key])) {
219
            $callbackresponse[$key] = trim($recording[$key]);
220
        }
221
    }
222
    return $callbackresponse;
223
}
224
225
/**
226
 * Callback for recording play.
227
 *
228
 * @param array $params
229
 *
230
 * @return string
231
 */
232
function bigbluebuttonbn_broker_recording_play($params) {
233
    $callbackresponse = array('status' => true, 'found' => false);
234
    $recordings = bigbluebuttonbn_get_recordings_array($params['idx'], $params['id']);
235 View Code Duplication
    if (array_key_exists($params['id'], $recordings)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
236
        // The recording was found.
237
        $callbackresponse = bigbluebuttonbn_broker_recording_info_current($recordings[$params['id']], $params);
238
    }
239
    $callbackresponsedata = json_encode($callbackresponse);
240
    return "{$params['callback']}({$callbackresponsedata});";
241
}
242
243
/**
244
 * Callback for recording action.
245
 * (publush/unpublish/protect/unprotect/edit/delete)
246
 *
247
 * @param array $bbbsession
248
 * @param array $params
249
 * @param boolean $showroom
250
 *
251
 * @return string
252
 */
253
function bigbluebuttonbn_broker_recording_action($bbbsession, $params, $showroom) {
254
    if (!$bbbsession['managerecordings']) {
255
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
256
        return;
257
    }
258
    // Retrieve array of recordings that includes real and imported.
259
    $bigbluebuttonbnid = null;
260
    if ($showroom) {
261
        $bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
262
    }
263
    $recordings = bigbluebuttonbn_get_allrecordings($bbbsession['course']->id, $bigbluebuttonbnid, $showroom,
264
        $bbbsession['bigbluebuttonbn']->recordings_deleted);
265
266
    $action = strtolower($params['action']);
267
    // Excecute action.
268
    $callbackresponse = bigbluebuttonbn_broker_recording_action_perform($action, $params, $recordings);
269
    if ($callbackresponse['status']) {
270
        // Moodle event logger: Create an event for action performed on recording.
271
        bigbluebuttonbn_event_log(\mod_bigbluebuttonbn\event\events::$events[$action], $bbbsession['bigbluebuttonbn'],
272
            ['other' => $params['id']]);
273
    }
274
    $callbackresponsedata = json_encode($callbackresponse);
275
    return "{$params['callback']}({$callbackresponsedata});";
276
}
277
278
/**
279
 * Helper for performing actions on recordings.
280
 * (publush/unpublish/protect/unprotect/edit/delete)
281
 *
282
 * @param string $action
283
 * @param array $params
284
 * @param array $recordings
285
 *
286
 * @return array
287
 */
288
function bigbluebuttonbn_broker_recording_action_perform($action, $params, $recordings) {
289
    if ($action == 'recording_publish') {
290
        return bigbluebuttonbn_broker_recording_action_publish($params, $recordings);
291
    }
292
    if ($action == 'recording_unpublish') {
293
        return bigbluebuttonbn_broker_recording_action_unpublish($params, $recordings);
294
    }
295
    if ($action == 'recording_edit') {
296
        return bigbluebuttonbn_broker_recording_action_edit($params, $recordings);
297
    }
298
    if ($action == 'recording_delete') {
299
        return bigbluebuttonbn_broker_recording_action_delete($params, $recordings);
300
    }
301
    if ($action == 'recording_protect') {
302
        return bigbluebuttonbn_broker_recording_action_protect($params, $recordings);
303
    }
304
    if ($action == 'recording_unprotect') {
305
        return bigbluebuttonbn_broker_recording_action_unprotect($params, $recordings);
306
    }
307
}
308
309
/**
310
 * Helper for performing publish on recordings.
311
 *
312
 * @param array $params
313
 * @param array $recordings
314
 *
315
 * @return array
316
 */
317 View Code Duplication
function bigbluebuttonbn_broker_recording_action_publish($params, $recordings) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
318
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
319
        // Execute publish on imported recording link, if the real recording is published.
320
        $realrecordings = bigbluebuttonbn_get_recordings_array(
321
            $recordings[$params['id']]['meetingID'], $recordings[$params['id']]['recordID']);
322
        // Only if the physical recording exist and it is published, execute publish on imported recording link.
323
        if (!isset($realrecordings[$params['id']])) {
324
            return array(
325
                'status' => false,
326
                'message' => get_string('view_recording_publish_link_deleted', 'bigbluebuttonbn')
327
            );
328
        }
329
        if ($realrecordings[$params['id']]['published'] !== 'true') {
330
            return array(
331
                'status' => false,
332
                'message' => get_string('view_recording_publish_link_not_published', 'bigbluebuttonbn')
333
            );
334
        }
335
        return array(
336
            'status' => bigbluebuttonbn_publish_recording_imported(
337
                $recordings[$params['id']]['imported'], true
338
            )
339
        );
340
    }
341
    // As the recordingid was not identified as imported recording link, execute actual publish.
342
    return array(
343
        'status' => bigbluebuttonbn_publish_recordings(
344
            $params['id'], 'true'
345
        )
346
    );
347
}
348
349
/**
350
 * Helper for performing unprotect on recordings.
351
 *
352
 * @param array $params
353
 * @param array $recordings
354
 *
355
 * @return array
356
 */
357 View Code Duplication
function bigbluebuttonbn_broker_recording_action_unprotect($params, $recordings) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
358
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
359
        // Execute unprotect on imported recording link, if the real recording is unprotected.
360
        $realrecordings = bigbluebuttonbn_get_recordings_array(
361
            $recordings[$params['id']]['meetingID'], $recordings[$params['id']]['recordID']);
362
        // Only if the physical recording exist and it is published, execute unprotect on imported recording link.
363
        if (!isset($realrecordings[$params['id']])) {
364
            return array(
365
                'status' => false,
366
                'message' => get_string('view_recording_unprotect_link_deleted', 'bigbluebuttonbn')
367
            );
368
        }
369
        if ($realrecordings[$params['id']]['protected'] === 'true') {
370
            return array(
371
                'status' => false,
372
                'message' => get_string('view_recording_unprotect_link_not_unprotected', 'bigbluebuttonbn')
373
            );
374
        }
375
        return array(
376
            'status' => bigbluebuttonbn_protect_recording_imported(
377
                $recordings[$params['id']]['imported'], false
378
            )
379
        );
380
    }
381
    // As the recordingid was not identified as imported recording link, execute actual uprotect.
382
    return array(
383
        'status' => bigbluebuttonbn_update_recordings(
384
            $params['id'], array('protect' => 'false')
385
        )
386
    );
387
}
388
389
/**
390
 * Helper for performing unpublish on recordings.
391
 *
392
 * @param array $params
393
 * @param array $recordings
394
 *
395
 * @return array
396
 */
397 View Code Duplication
function bigbluebuttonbn_broker_recording_action_unpublish($params, $recordings) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
398
    global $DB;
399
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
400
        // Execute unpublish or protect on imported recording link.
401
        return array(
402
            'status' => bigbluebuttonbn_publish_recording_imported(
403
                $recordings[$params['id']]['imported'], false
404
            )
405
        );
406
    }
407
    // As the recordingid was not identified as imported recording link, execute unpublish on a real recording.
408
    // First: Unpublish imported links associated to the recording.
409
    $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
410
    foreach ($importedall as $key => $record) {
411
        $meta = json_decode($record->meta, true);
412
        // Prepare data for the update.
413
        $meta['recording']['published'] = 'false';
414
        $importedall[$key]->meta = json_encode($meta);
415
        // Proceed with the update.
416
        $DB->update_record('bigbluebuttonbn_logs', $importedall[$key]);
417
    }
418
    // Second: Execute the actual unpublish.
419
    return array(
420
        'status' => bigbluebuttonbn_publish_recordings(
421
            $params['id'], 'false'
422
        )
423
    );
424
}
425
426
/**
427
 * Helper for performing protect on recordings.
428
 *
429
 * @param array $params
430
 * @param array $recordings
431
 *
432
 * @return array
433
 */
434 View Code Duplication
function bigbluebuttonbn_broker_recording_action_protect($params, $recordings) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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

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

Loading history...
435
    global $DB;
436
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
437
        // Execute unpublish or protect on imported recording link.
438
        return array(
439
            'status' => bigbluebuttonbn_protect_recording_imported(
440
                $recordings[$params['id']]['imported'], true
441
            )
442
        );
443
    }
444
    // As the recordingid was not identified as imported recording link, execute protect on a real recording.
445
    // First: Protect imported links associated to the recording.
446
    $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
447
    foreach ($importedall as $key => $record) {
448
        $meta = json_decode($record->meta, true);
449
        // Prepare data for the update.
450
        $meta['recording']['protected'] = 'true';
451
        $importedall[$key]->meta = json_encode($meta);
452
        // Proceed with the update.
453
        $DB->update_record('bigbluebuttonbn_logs', $importedall[$key]);
454
    }
455
    // Second: Execute the actual protect.
456
    return array(
457
        'status' => bigbluebuttonbn_update_recordings(
458
            $params['id'], array('protect' => 'true')
459
        )
460
    );
461
}
462
463
/**
464
 * Helper for performing delete on recordings.
465
 *
466
 * @param array $params
467
 * @param array $recordings
468
 *
469
 * @return array
470
 */
471
function bigbluebuttonbn_broker_recording_action_delete($params, $recordings) {
472
    global $DB;
473
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
474
        // Execute delete on imported recording link.
475
        return array(
476
            'status' => bigbluebuttonbn_delete_recording_imported(
477
                $recordings[$params['id']]['imported']
478
            )
479
        );
480
    }
481
    // As the recordingid was not identified as imported recording link, execute delete on a real recording.
482
    // First: Delete imported links associated to the recording.
483
    $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
484
    if ($importedall > 0) {
485
        foreach (array_keys($importedall) as $key) {
486
            // Execute delete on imported links.
487
            $DB->delete_records('bigbluebuttonbn_logs', array('id' => $key));
488
        }
489
    }
490
    // Second: Execute the actual delete.
491
    return array(
492
        'status' => bigbluebuttonbn_delete_recordings($params['id'])
493
    );
494
}
495
496
/**
497
 * Helper for performing edit on recordings.
498
 *
499
 * @param array $params
500
 * @param array $recordings
501
 *
502
 * @return array
503
 */
504
function bigbluebuttonbn_broker_recording_action_edit($params, $recordings) {
505
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
506
        // Execute update on imported recording link.
507
        return array(
508
            'status' => bigbluebuttonbn_update_recording_imported(
509
                $recordings[$params['id']]['imported'], json_decode($params['meta'], true)
510
            )
511
        );
512
    }
513
514
    // As the recordingid was not identified as imported recording link, execute update on a real recording.
515
    // (No need to update imported links as the update only affects the actual recording).
516
    // Execute update on actual recording.
517
    return array(
518
        'status' => bigbluebuttonbn_update_recordings(
519
            $params['id'], json_decode($params['meta'])
520
        )
521
    );
522
}
523
524
/**
525
 * Helper for responding when recording ready is performed.
526
 *
527
 * @param array $params
528
 * @param object $bigbluebuttonbn
529
 *
530
 * @return void
531
 */
532
function bigbluebuttonbn_broker_recording_ready($params, $bigbluebuttonbn) {
533
    // Decodes the received JWT string.
534
    try {
535
        $decodedparameters = \Firebase\JWT\JWT::decode($params['signed_parameters'],
536
            \mod_bigbluebuttonbn\locallib\config::get('shared_secret'), array('HS256'));
537
    } catch (Exception $e) {
538
        $error = 'Caught exception: '.$e->getMessage();
539
        header('HTTP/1.0 400 Bad Request. '.$error);
540
        return;
541
    }
542
    // Validate that the bigbluebuttonbn activity corresponds to the meeting_id received.
543
    $meetingidelements = explode('[', $decodedparameters->meeting_id);
544
    $meetingidelements = explode('-', $meetingidelements[0]);
545
546
    if (!isset($bigbluebuttonbn) || $bigbluebuttonbn->meetingid != $meetingidelements[0]) {
547
        header('HTTP/1.0 410 Gone. The activity may have been deleted');
548
        return;
549
    }
550
    // Sends the messages.
551
    try {
552
        // Workaround for CONTRIB-7438.
553
        // Proceed as before when no record_id is provided.
554
        if (!isset($decodedparameters->record_id)) {
555
            bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn);
556
            header('HTTP/1.0 202 Accepted');
557
            return;
558
        }
559
        // We make sure messages are sent only once.
560
        if (bigbluebuttonbn_get_count_callback_event_log($decodedparameters->record_id) == 0) {
561
            bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn);
562
        }
563
        $overrides = array('meetingid' => $decodedparameters->meeting_id);
564
        $meta['recordid'] = $decodedparameters->record_id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$meta was never initialized. Although not strictly required by PHP, it is generally a good practice to add $meta = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
565
        $meta['callback'] = 'recording_ready';
566
        bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTON_LOG_EVENT_CALLBACK, $overrides, json_encode($meta));
567
        header('HTTP/1.0 202 Accepted');
568
    } catch (Exception $e) {
569
        $error = 'Caught exception: '.$e->getMessage();
570
        header('HTTP/1.0 503 Service Unavailable. '.$error);
571
    }
572
}
573
574
/**
575
 * Helper for performing import on recordings.
576
 *
577
 * @param array $bbbsession
578
 * @param array $params
579
 *
580
 * @return string
581
 */
582
function bigbluebuttonbn_broker_recording_import($bbbsession, $params) {
583
    global $SESSION;
584
    if (!$bbbsession['managerecordings']) {
585
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
586
        return;
587
    }
588
    $importrecordings = $SESSION->bigbluebuttonbn_importrecordings;
589
    if (!isset($importrecordings[$params['id']])) {
590
        $error = "Recording {$params['id']} could not be found. It can not be imported";
591
        header('HTTP/1.0 404 Not found. '.$error);
592
        return;
593
    }
594
    $callbackresponse = array('status' => true);
595
    $importrecordings[$params['id']]['imported'] = true;
596
    $overrides = array('meetingid' => $importrecordings[$params['id']]['meetingID']);
597
    $meta = '{"recording":'.json_encode($importrecordings[$params['id']]).'}';
598
    bigbluebuttonbn_log($bbbsession['bigbluebuttonbn'], BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, $overrides, $meta);
599
    // Moodle event logger: Create an event for recording imported.
600
    if (isset($bbbsession['bigbluebutton']) && isset($bbbsession['cm'])) {
601
        bigbluebuttonbn_event_log(\mod_bigbluebuttonbn\event\events::$events['recording_import'], $bbbsession['bigbluebuttonbn'],
602
            ['other' => $params['id']]);
603
    }
604
    $callbackresponsedata = json_encode($callbackresponse);
605
    return "{$params['callback']}({$callbackresponsedata});";
606
}
607
608
/**
609
 * Helper for responding when storing live meeting events is requested.
610
 *
611
 * The callback with a POST request includes:
612
 *  - Authentication: Bearer <A JWT token containing {"exp":<TIMESTAMP>} encoded with HS512>
613
 *  - Content Type: application/json
614
 *  - Body: <A JSON Object>
615
 *
616
 * @param object $bigbluebuttonbn
617
 *
618
 * @return void
619
 */
620
function bigbluebuttonbn_broker_meeting_events($bigbluebuttonbn) {
621
    // Decodes the received JWT string.
622
    try {
623
        // Get the HTTP headers (getallheaders is a PHP function that may only work with Apache).
624
        $headers = getallheaders();
625
626
        // Pull the Bearer from the headers.
627
        if (!array_key_exists('Authorization', $headers)) {
628
            $msg = 'Authorization failed';
629
            header('HTTP/1.0 400 Bad Request. ' . $msg);
630
            return;
631
        }
632
        $authorization = explode(" ", $headers['Authorization']);
633
634
        // Verify the authenticity of the request.
635
        $token = \Firebase\JWT\JWT::decode($authorization[1],
0 ignored issues
show
Unused Code introduced by
$token is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
636
            \mod_bigbluebuttonbn\locallib\config::get('shared_secret'), array('HS512'));
0 ignored issues
show
Bug introduced by
It seems like \mod_bigbluebuttonbn\loc...g::get('shared_secret') targeting mod_bigbluebuttonbn\locallib\config::get() can also be of type boolean or null; however, Firebase\JWT\JWT::decode() does only seem to accept string|array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
637
638
        // Get JSON string from the body.
639
        $jsonstr = file_get_contents('php://input');
640
641
        // Convert JSON string to a JSON object.
642
        $jsonobj = json_decode($jsonstr);
643
    } catch (Exception $e) {
644
        $msg = 'Caught exception: ' . $e->getMessage();
645
        header('HTTP/1.0 400 Bad Request. ' . $msg);
646
        return;
647
    }
648
649
    // Validate that the bigbluebuttonbn activity corresponds to the meeting_id received.
650
    $meetingidelements = explode('[', $jsonobj->{'meeting_id'});
651
    $meetingidelements = explode('-', $meetingidelements[0]);
652
    if (!isset($bigbluebuttonbn) || $bigbluebuttonbn->meetingid != $meetingidelements[0]) {
653
        $msg = 'The activity may have been deleted';
654
        header('HTTP/1.0 410 Gone. ' . $msg);
655
        return;
656
    }
657
658
    // We make sure events are processed only once.
659
    $overrides = array('meetingid' => $jsonobj->{'meeting_id'});
660
    $meta['recordid'] = $jsonobj->{'internal_meeting_id'};
0 ignored issues
show
Coding Style Comprehensibility introduced by
$meta was never initialized. Although not strictly required by PHP, it is generally a good practice to add $meta = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
661
    $meta['callback'] = 'meeting_events';
662
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTON_LOG_EVENT_CALLBACK, $overrides, json_encode($meta));
663
    if (bigbluebuttonbn_get_count_callback_event_log($jsonobj->{'internal_meeting_id'}, 'meeting_events') == 1) {
664
        // Process the events.
665
        bigbluebuttonbn_process_meeting_events($bigbluebuttonbn, $jsonobj);
666
        $msg = 'Enqueued.';
667
        header('HTTP/1.0 202 Accepted. ' . $msg);
668
        return;
669
    }
670
    $msg = 'Already processed.';
671
    header('HTTP/1.0 202 Accepted. ' . $msg);
672
}
673
674
/**
675
 * Helper for validating the parameters received.
676
 *
677
 * @param array $params
678
 *
679
 * @return string
680
 */
681
function bigbluebuttonbn_broker_validate_parameters($params) {
682
    $action = strtolower($params['action']);
683
    $requiredparams = bigbluebuttonbn_broker_required_parameters();
684
    if (!array_key_exists($action, $requiredparams)) {
685
        return 'Action '.$params['action'].' can not be performed.';
686
    }
687
    return bigbluebuttonbn_broker_validate_parameters_message($params, $requiredparams[$action]);
688
}
689
690
/**
691
 * Helper for responding after the parameters received are validated.
692
 *
693
 * @param array $params
694
 * @param array $requiredparams
695
 *
696
 * @return string
697
 */
698
function bigbluebuttonbn_broker_validate_parameters_message($params, $requiredparams) {
699
    foreach ($requiredparams as $param => $message) {
700
        if (!array_key_exists($param, $params) || $params[$param] == '') {
701
            return $message;
702
        }
703
    }
704
}
705
706
/**
707
 * Helper for definig rules for validating required parameters.
708
 */
709
function bigbluebuttonbn_broker_required_parameters() {
710
    $params['server_ping'] = [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
711
        'callback' => 'This request must include a javascript callback.',
712
        'id' => 'The meetingID must be specified.'
713
    ];
714
    $params['meeting_info'] = [
715
        'callback' => 'This request must include a javascript callback.',
716
        'id' => 'The meetingID must be specified.'
717
    ];
718
    $params['meeting_end'] = [
719
        'callback' => 'This request must include a javascript callback.',
720
        'id' => 'The meetingID must be specified.'
721
    ];
722
    $params['recording_play'] = [
723
        'callback' => 'This request must include a javascript callback.',
724
        'id' => 'The recordingID must be specified.'
725
    ];
726
    $params['recording_info'] = [
727
        'callback' => 'This request must include a javascript callback.',
728
        'id' => 'The recordingID must be specified.'
729
    ];
730
    $params['recording_links'] = [
731
        'callback' => 'This request must include a javascript callback.',
732
        'id' => 'The recordingID must be specified.'
733
    ];
734
    $params['recording_publish'] = [
735
        'callback' => 'This request must include a javascript callback.',
736
        'id' => 'The recordingID must be specified.'
737
    ];
738
    $params['recording_unpublish'] = [
739
        'callback' => 'This request must include a javascript callback.',
740
        'id' => 'The recordingID must be specified.'
741
    ];
742
    $params['recording_delete'] = [
743
        'callback' => 'This request must include a javascript callback.',
744
        'id' => 'The recordingID must be specified.'
745
    ];
746
    $params['recording_protect'] = [
747
        'callback' => 'This request must include a javascript callback.',
748
        'id' => 'The recordingID must be specified.'
749
    ];
750
    $params['recording_unprotect'] = [
751
        'callback' => 'This request must include a javascript callback.',
752
        'id' => 'The recordingID must be specified.'
753
    ];
754
    $params['recording_edit'] = [
755
        'callback' => 'This request must include a javascript callback.',
756
        'id' => 'The recordingID must be specified.',
757
        'meta' => 'A meta parameter should be included'
758
    ];
759
    $params['recording_import'] = [
760
        'callback' => 'This request must include a javascript callback.',
761
        'id' => 'The recordingID must be specified.'
762
    ];
763
    $params['recording_ready'] = [
764
        'bigbluebuttonbn' => 'The BigBlueButtonBN instance ID must be specified.',
765
        'signed_parameters' => 'A JWT encoded string must be included as [signed_parameters].'
766
    ];
767
    $params['meeting_events'] = [
768
        'bigbluebuttonbn' => 'The BigBlueButtonBN instance ID must be specified.'
769
    ];
770
    return $params;
771
}
772
773
/**
774
 * Helper for validating if a recording is an imported link or a real one.
775
 *
776
 * @param array $recordings
777
 * @param string $recordingid
778
 *
779
 * @return boolean
780
 */
781
function bigbluebuttonbn_broker_recording_is_imported($recordings, $recordingid) {
782
    return (isset($recordings[$recordingid]) && isset($recordings[$recordingid]['imported']));
783
}
784